Memory management in Javascript [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I learnt programming with C/C++, so memory management in Javascript is never intuitive to me.
I know that all variables are located in heap memory rather than in stack memory, so memory operations are quite expensive. If all references to a variable are not accessible anymore, it can be garbage collected, but it looks like V8 won't immediately do garbage collection? (Observed with --trace_gc)
To free memory of a global array object, this can be done by array = null, will array = [] have the same effect? (I need the variable to behave like an array even after I clear it).
From my experience, String and Number are passed to functions by value while Object and Array are passed to functions by reference. If String is very large and the function actually allows it to be passed by reference safely (only read the string), will V8 optimizes like that?
ES6 introduces let keyword for block-scope declaration, but a single use of let makes the whole function becomes slower, so I still stick to var even though let/const are closer to C/C++ which I am familiar with. (Tested using d8 built right from master branch, I am aware that V8 developers are actively working on this bug).
Trying to use Chrome DevTools to learn my code's memory management, but couldn't figure what those graphs and charts from profiler actually mean.

Basically, you do c++ when you want to manage your memory and a whole bunch of quite technical stuff yourself.
If you don't want you go for c#/Java because there is a virtual machine managing the memory.
Same goes for JavaScript the browser manage the memory, and unless you're loading a page with thousands of elements or writing a library to display / compute over thousands of data you won't have any memory problem.
Note that array = [] will affect the reference of a new empty array when array = null will dereference the existing array. Since it's null, if you try to use it won't work, so go for the array=[].
If you're still not convinced, then just use an appropriate library to do the work for you.

Related

Where does Javascript allocate memory for the result of a function call? Stack or heap?

I have looked all over the internet and I can't seem to find an answer to this question.
I read that the stack is used to store primitives and heap is for objects.
I also read that the stack's size is fixed and once allocated it does not change, hence why it's used for primitives, because JS knows the size of each variable before runtime.
I also know that primitives are immutable, so if we try to reassign a variable, it will not change the value at its memory address but will rather allocate new space in memory, store the new value and assign its address to the variable.
If the above is correct, then what happens when I do this?
let string = "Hello World"; // Memory allocated for "Hello World"
string = string.ToUpperCase(); // New memory allocated for "HELLO WORLD"
Where does the new memory for HELLO WORLD get allocated? Is it in the stack because it's a primitive? Or is it in the heap because JS does not know its value until it runs the code?
If it's in the stack, what happens to the old "Hello World" then? Since only the heap is garbage collected does that mean that the old, unused, string will stay there until the program finishes running?
What happens if I do
string = string.repeat(10000000000)
If the stack can't grow, does it mean that at some point I can stack overflow because a variable is too large?
Thank you.
The answer may vary by engine, and it really doesn't matter to your code. Worry about running out of stack if/when you run out of stack. JavaScript's specification doesn't require implementations to do one thing or the other. It describes behavior, not the implementation of that behavior.
But speaking practically: It seems unlikely that a JavaScript engine would try to put a massive string on the stack. More likely, it would put it in the heap. That doesn't mean it can't put other strings on the stack. Maybe it decides based on size. Maybe it decides based on lifetime — perhaps it'll put a small string used only locally in a function on the stack, but put a massive one, or one retained globally, on the heap.
The point is: Modern JavaScript engines are complicated and highly, highly optimized. They're unlikely to take such a simplistic view as "primitives go on the stack and objects go on the heap."
I read that the stack is used to store primitives and heap is for objects.
Not necessarily. Objects can be allocated on the stack as well, and have been by at least some JavaScript engines at various points in history. If an object won't survive the end of the function call, and isn't massive, putting it on the stack makes reclaiming it when the function returns dead easy.
I also know that primitives are immutable, so if we try to reassign a variable, it will not change the value at its memory address but will rather allocate new space in memory, store the new value and assign its address to the variable.
Without getting too deep into theory, again this could well be implementation-specific. Consider a = 1. We have no way of telling whether that puts the value 1 in the memory associated with a, or puts a reference to an immutable singleton representing 1 in a. The former seems more a lot more likely than the latter (for numbers; strings are another matter), but we don't know and can't know (in the general case; we can for a specific version of a specific engine), because it makes no difference to our code and the spec doesn't require one behavior or the other.

For loop VS For Each in javascript [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
The community reviewed whether to reopen this question 2 months ago and left it closed:
Needs details or clarity Add details and clarify the problem by editing this post.
Improve this question
What is the current standard in 2017 in Javascript with for() loops vs a .forEach.
I am currently working my way through Colt Steeles "Web Dev Bootcamp" on Udemy and he favours forEach over for in his teachings. I have, however, searched for various things during the exercises as part of the course work and I find more and more recommendations to use a for-loop rather than forEach. Most people seem to state the for loop is more efficient.
Is this something that has changed since the course was written (circa 2015) or are their really pros and cons for each, which one will learn with more experience.
Any advice would be greatly appreciated.
for
for loops are much more efficient. It is a looping construct specifically designed to iterate while a condition is true, at the same time offering a stepping mechanism (generally to increase the iterator). Example:
for (var i=0, n=arr.length; i < n; ++i ) {
...
}
This isn't to suggest that for-loops will always be more efficient, just that JS engines and browsers have optimized them to be so. Over the years there have been compromises as to which looping construct is more efficient (for, while, reduce, reverse-while, etc) -- different browsers and JS engines have their own implementations that offer different methodologies to produce the same results. As browsers further optimize to meet performance demands, theoretically [].forEach could be implemented in such a way that it's faster or comparable to a for.
Benefits:
efficient
early loop termination (honors break and continue)
condition control (i<n can be anything and not bound to an array's size)
variable scoping (var i leaves i available after the loop ends)
forEach
.forEach are methods that primarily iterate over arrays (also over other enumerable, such as Map and Set objects). They are newer and provide code that is subjectively easier to read. Example:
[].forEach((val, index)=>{
...
});
Benefits:
does not involve variable setup (iterates over each element of the array)
functions/arrow-functions scope the variable to the block
In the example above, val would be a parameter of the newly created function. Thus, any variables called val before the loop, would hold their values after it ends.
subjectively more maintainable as it may be easier to identify what the code is doing -- it's iterating over an enumerable; whereas a for-loop could be used for any number of looping schemes
Performance
Performance is a tricky topic, which generally requires some experience when it comes to forethought or approach. In order to determine ahead of time (while developing) how much optimization may be required, a programmer must have a good idea of past experience with the problem case, as well as a good understanding of potential solutions.
Using jQuery in some cases may be too slow at times (an experienced developer may know that), whereas other times may be a non-issue, in which case the library's cross-browser compliance and ease of performing other functions (e.g., AJAX, event-handling) would be worth the development (and maintenance) time saved.
Another example is, if performance and optimization was everything, there would be no other code than machine or assembly. Obviously that isn't the case as there are many different high level and low level languages, each with their own tradeoffs. These tradeoffs include, but are not limited to specialization, development ease and speed, maintenance ease and speed, optimized code, error free code, etc.
Approach
If you don't have a good understanding if something will require optimized code, it's generally a good rule of thumb to write maintainable code first. From there, you can test and pinpoint what needs more attention when it's required.
That said, certain obvious optimizations should be part of general practice and not required any thought. For instance, consider the following loop:
for (var i=0; i < arr.length; ++i ){}
For each iteration of the loop, JavaScript is retrieving the arr.length, a key-lookup costing operations on each cycle. There is no reason why this shouldn't be:
for (var i=0, n=arr.length; i < n; ++i){}
This does the same thing, but only retrieves arr.length once, caching the variable and optimizing your code.

How many Vars is too many in JS? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have a page I am building, and our solution to a problem involved wrapping some code inside a function then calling that when required.
Now the page is growing, and each item has its own function. According to D. Crockford each function is put in a VAR anyway so:
function functionName(){}
is equivalent to:
var var1 = functionName(){}
So now we have LOTS of vars in the page (I have also written them specifically in the latter format as Mr. Crockford promotes) and I am getting worried this creates too many variables (not sure this will cause any issues, performance or otherwise). I am thinking of making a single Object Literal and adding each function as a value to a key. This I think will reduce all these vars into a single manageable unit and reduce the amount of variables I am using (and avoid any potential issues) - or will it?
Thanks!
var keyword is actually being used in order to manage variable scope.
Not using var keyword makes the variable a global one. The memory occupied by the variables are cleared when the variable isn't used anymore. Most of the modern browsers contains a garbage collector responsible for freeing up the unused spaces. So it's suggested that using var keyword in blocks would make your js interpreter search less for the variable, otherwise it will search the whole document in order to get the value.
In performance terms it doesn't matter, you can use as many variables as you want, the performance only will be affected by the tasks performed in the function.
As you keep increasing the variables, the heap limit set by the relevant JS engine will come into play.
For eg - V8 engine seems to have it set to 1.4 GB
If you do ever run out of that, it's high time you recheck the code & stop blaming JS.
On a serious note, from a practical point of view, that's an enormous limit, which tells you that you don't need to worry about it so much.
Besides your friendly neighborhood GC will always keep cleaning up & ensure you live lavishly with variables.
Encapsulating your code in a namespace is a good idea but you won't save memory or get a performance boost that way. From performance perspective both ways you've shown are the same.
There is a convention to avoid nameclashing however based on reverted domain - imagine a JS lib made for SO:
// The following two lines are to protect namespace from overwriting and allow to
// extend them easily
if (!com) var com = {};
if (!com.stackoverflow) com.stackoverflow = {};
com.stackoverflow.renderSomething = function(){
// Some very clever code here
};
There is nothing else you can gain this way but it's worth to organize your code this way.
And just to clarify:
function functionName(){};
is almost the same as
var functionName = function(){};
Almost because in the first form functionName is defined at parse-time and the latter form defines functionName at run-time.

Can I speed up calls to native methods in JavaScript? [duplicate]

This question already has answers here:
Is a closure for dereferencing variables useful?
(3 answers)
Closed 9 years ago.
According to this answer to 'Is object empty?':
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
I've seen several implementations of something similar in small JavaScript libraries, like:
var slice = Array.prototype.slice;
//or
function slice(collection) {
return Array.prototype.slice.call(collection);
}
I did a quick jsperf to test this sort of thing, and caching looked a bit quicker overall than not caching, but my test could be flawed.
(I am using the word 'cache' to mean storing the method inside a variable.)
The context of this question is when a developer needs to call the native method multiple times, and what the observable difference would be.
Does caching the native method prevent the engine from having to look inside the object for the method every time the method is called, thus making caching a faster way to call native methods whenever the developer needs to call the same native method more than once?
When you're using Array.prototype.slice a lot in, say, a library, it makes sense to create a variable holding that function (var slice = Array.prototype.slice;) because the variable can be minified by a JavaScript minifier which it can't otherwise.
Assigning the function to a variable also avoids having to traverse the object's prototype chain, which might result in a slightly better performance.
Note that this is micro-optimization, which you (generally speaking) shouldn't concern yourself too much with – leave that up to a modern JavaScript engine.
Saving the value in a variable presents some optimization opportunities because if its a local variable the interpreter could do analyisis to realize that the vatiable never gets mutated. On the other hand, you always need to dereference globals like Array, since everyone could potentially change them at any time.
That said, I have no idea if this is going to matter for performance, expecially once you consider the JIT optimizations.
Usually, the biggest reason people use var slice is to keep the source code short.

Global variables in JS harmful? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
According to this article
http://www.mediaevent.de/javascript/globale-lokale-variablen.html
Global variables are in JS pretty dangerous.
I'm sorry that it's in German, but I'm gonna point out out the 2 main statements of the article.
The first is already in the 2nd paragraph of the head statement.
It says something like "In JS global var's are dangerous as they can get accessed by other scripts over the name" That's fine so far, as that's mostly the way why I want to use global var's don't I?
But in the article it sounds as this could happen randomly. and that's for sure not the expected behaving, is it?
But what is much more frightening me is the second last sentence. It forecasts that memory leaks will generated if a function that declares a
global variable is called multiple times.
But how could this happen if the name is still the same? how there can be multiple vars declared global with the same name?
Or is this article probably written by some one just "half-knowledge"? Or maybe just addressed to some one who isn't used to the difference between global and local at all?
Or is JS really behaving in this way?
Now a concrete example:
I want some one who logs in to my page to create a Random generated token and submit it by clicking login.
on each other button I want that this token is accessed by a different function and just submit it, so that just for a new login the key will be regenerated.
For that key I was thinking about using a global variable, which gets declared by one function and gets returned by another.
But as I will generate/regenerate the key possibly more then once, would this generate memory leaks? Or is this article I'm referring to probably just dramatizing?
If this is really the way JS is behaving, what would be a good way to make a variable accessable from different functions in my case?
The problem with globals is not memory, and it's not performance.
The problems with globals is entirely different. The problems are that they introduce global state and that scripts are not bound to a namespace.
Let's go through these problems one by one.
Having global state
This is the biggest issue here. Coding necessitates that the dependencies of a module be explicit and that communication between pieces of code is very clear.
When you have global variables which part of the code uses the variable is not nearly as clear and you can't be sure what part of the code needs it and what does not.
Let's say I have a Zoo project and I have a Bathe service that cleans an animal. Instead of passing Bathe around to each animal that needs it I have it on a global namespace and I just call Bathe(myAnimal).
Now I want to restructure my zoo and I want to know which animals need bathing because I want to optimize that. I have no way of knowing that other than going through my whole code. In order to see if my Giraffe needs bathing I have to read the entire code of the Giraffe class. If instead I passed Bathe to the constructor of Giraffe instead of using it or creating it inside giraffe (a concept called dependency injection) I can see that a Giraffe needs bathing just by reading the signature.
Now this can get way worse, what if I have state? If I'm actually changing a global variable in multiple places it becomes extremely hard to track. In a more than a few lines code base this means that you have state changing all around and no clear indication of who is changing it.
This is the main reason you should avoid globals altogether .
Scripts are not bound to a namespace
If I have two scripts on a page and my first script declares a A variable on the global namespace, the second script can access that variable. This is useful because scripts can interact this way but it's very harmful because it means that scripts can override each other's code, and communicate in an unclear way.
This of course is completely mitigated if you use a module loader like browserify or RequireJS which means your whole script only exposes two globals - require and define and then script loading is done through the loader.
This way the way independent pieces of code interact is well defined. That doesn't prevent you from creating variables on the global object, but it helps mitigating the need to do so in a uniform manner.
A note on security
Of course, anything on the client side is compromised, you can't do security or anything like that in client side JavaScript on an insecure browser (that is, you didn't prevent anything external on) because the client can just run arbitrary code on your code and read it.
There are three big problems with global variables:
name collisions
code complexity
garbage collection
Name collision
The problem with having variables in global scope is that you have less control over what else is in that scope. Your code uses a ga_ variable globally and works fine, but when you add a Google Analytics snippet that uses the same variable things unexpectedly fail and it can be quite hard to see why your shopping cart fails 2 out of 3 page loads.
If you can wrap your code in an IIFE to prevent having any variables in global scope, you should do that. Obviously there are cases where you actually want to have your code accessible globally (ex: jQuery library). In those cases, it is best practice to keep all your stuff in a single namespace (jQuery) with a relevant name.
Code complexity
It is usually a good idea to partition your code so that individual pieces have minimal interactions with each other. The more pieces interact the harder it is to make changes and to track down where bugs come from. Obviously a global variable can be accessed anywhere so when you have a problem with some code that accesses a global variable, you have to inspect every usage of that variable which can be quite a big pain. The thing to do to avoid these pains is to keep variables as local as they can be and encapsulate pieces of code so they can't interact with each other except through specific interfaces.
Memory leaks
In JavaScript you have little control over the garbage collection process. All that is guaranteed is that if you can access a variable it will not be garbage collected. This means that if you want something to be garbage collected, then you must make sure you can't access it anymore. While a global i variable which keeps a number won't be a big deal, as #Boluc Papuaccoglu mentioned when your global variable keeps more and more properties over time (an array of XHR requests for example, or array of created DOM objects), the memory consumption turn into a big deal.
All of these situations are worst case scenarios and you probably won't have issues with a small application. These recomendations have most value when you're starting to learn programming because they develop good habits and when you're working on complex applications when they save you time and money wasted on debug or difficult to do improvements.
Regarding memory leaks: Let's say you have a function, and within it you define a var, and use it for some purpose then return from the function. In this case, the memory used by the variable will be freed. However, if you relied on a global variable to do the same thing, then the memory would continue to be allocated long after your function exited. Extending the same scenario, imagine that your function adds properties to this variable with names that depend on the data the function is processing (like Order ID, Customer Name, etc.) Now, each time your function gets called, more and more properties will be appended to this variable and it will grow and grow.

Categories