Are WebGL objects garbage collected? - javascript

In JavaScript memory that I allocated (e.g. an ArrayBuffer) gets freed up when I don't have any reference to it anymore by the GC as I understood that right?
WebGL objects like Buffers or Textures are associated with a memory block on the GPU as allocated by gl.bufferData() or gl.textureImage2D().
I'm wondering: if I give up my last reference to a WebGLTexture or WebGLBuffer object, does it get garbage collected with its GPU memory block freed by the JavaScript VM automatically?

Yes
From spec
Note that underlying GL object will be automatically marked for deletion when the JS object is destroyed
But you should notice that the object would probably not destroyed at the time you give up the last reference, so it's still a good practice to call deleteBuffer.

Copied from this answer: Are WebGLTextures garbage collected?
with the word WebGLTexture changed to WebGLObject
Yes and no.
Yes they are garbage collected. But garbage collection happens whenever the browser decides to collect them. From the POV of most browser JavaScript engines the WebGLObject object is a tiny object that just contains an int so it has no easy way to know of any special pressure to collect it. In other words when the GPU runs out of memory the JavaScript garbage collector, which has no connection to the GPU, has no way of knowing that it needs to free these tiny WebGLObject objects in order to free up texture memory. It's only looking at CPU memory.
This is actually a well known problem of garbage collection. It's great for memory. It's not so great for other resources.
So, yes, WebGLObject objects are garbage collected and yes the texture/buffer/renderbuffer/program/shader will be freed but practically speaking you need to delete them yourself if you don't want to run out of memory.
Of course the browser will free them all if you refresh the page or visit a new page in the same tab but you can't count on the browser to garbage collect WebGLObject objects (textures/buffers/renderbuffers/programs/shaders) in any useful way.

Related

When is javascript code considered garbage for the GC

So i've been getting into the more advanced parts of javascript. Right now im learning about memory, memory leaks and garbage collecting. Many examples on the web just exaplain what the garbage collector is , but i am having trouble finding one that tells me when the code is considered garbage for the garbage collector.
So far I've read "When there's no longer a reference pointing to an object". Is that the only case? What exactly do they mean by that.
Thanks in advance.
It's better to see it as code being reachable or not from the roots, and roots are values that are inherently always reachable, such as global variables. The garbage collector in JS uses a "mark and sweep" algorithm, where it starts from the roots and visits each reference and their references and so on. Once it's visited, it gets marked as being visited/reachable together with all reachable references from there, and will not be visited again.
You can have references pointing to objects, which maybe also have references to other objects, but once they can never be reached anymore from the root, they form a sort of unreachable island of references. They will never get visited and will finally be sweeped away by the garbage collector.
There are also several optimizations done. For example some objects get created and do their job once and then die off. Those new ones get cleaned up very aggressively and fast. If they are used for longer periods of time they will be considered old, and will be visited less often to check if they should be garbage collected.

JavaScript - large for loop, should I release objects?

I have a for loop that iterates over a fair few items.
At the start of each iteration I use the same var newObj = new ...
However, I'm wondering, is this completely replacing that object each time or should I be releasing it at the end of each iteration.
If I should release - how do I do release?
For example - say x is a large number (10.000 as a high example)
for (var x = 0; x<10000; x++) {
var newObj = new someThing(x, y, z)
newObj.dance()
newObj.andDanceMore()
//Should I do some kind of release here - or am I replacing it each time
}
Thanks.
in javascript you don't have to worry about "releasing" allocated memmory,
from the great MDN docs
High-level languages (such as JS) embed a piece of software called "garbage
collector" whose job is to track memory allocation and use in order to
find when a piece of allocated memory is not needed any longer in
which case, it will automatically free it. This process is an
approximation since the general problem of knowing whether some piece
of memory is needed is undecidable (can't be solved by an algorithm).
basically the general behavior of the G.C is when an object has zero references to it - It can be garbage collected.
in the case you reffering to, each time you assigning a new value to var newObj, the G.C detect that there are 0 reffernces to it and garbage collected it - releasing it -
Short answer: no.
Slightly longer answer: There is no manual memory management in JavaScript. It is a garbage collected language. Each time the GC is launched (and you have no control over when that happens), all objects that have no references will be automatically collected, effectively freeing the memory they occupied.
Further reading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management
Do you know what Garbage Collector is? If not, you could find very nice blogposts googling "node.js garbage collection".
In brief:
1) When you override the variable value (or local variable is being dropped with its scope), the object still remains in memory.
2) When Node.js decides to run garbage collector, your object will be wiped out from memory in the following cases:
2.1) There are no variables, containing it (actually pointing to it).
2.2) There are some variables/properties pointing to it, but the entire cluster of objects and closures with mutual links is identified as isolated.
3) You may force garbage collector run (How to request the Garbage Collector in node.js to run?), but in regular cases you do not need this.
4) Difference between let and var, mentioned in comments, does not affect your case. Yes, let is more local than var, but what? If Node.js drops let variable quitting the loop, or you override any variable (var, let, property - whatever) with new value, the result is the same.
var newObj
Will be executed only once.What the program did is that Constantly assigned to newObj in the loop, objects that are not referenced will be recycled by GC.

Is there a way to control Chrome GC?

I am working with quite large volume of data.
Mechanism:
JavaScript is reading WebSQL database, then assembles data into Object that has tree structure.
Then applies to tree object knockout.js (makes elements observable) then data-binds
and then applies Jquery Mobile UI at the end.
Whole process takes unacceptable amount of time.
I have already optimized algorithm that makes tree object out of data,
also optimised conversion to observables mechanism by pushing items directly into ko.observable arrays and calling hasMutated only once.
I am applying knockout.js IF bindings to not process invisible tree nodes in UI until parent is opened.
Performance here is key.
After inspecting page load in timeline in Chrome developer tools I have noticed that Garbage Collector is doing cleans on every concurrent call when I am building tree object.
Question: Is there a way to temporarily disable Chrome GC and then enable it again after I am done with page processing?
P.S I know I could add reference to part that gets collected, basically introduce object that dominates and prevents GC collection, but this would require substantial changes through the code, and I am not sure I could keep it long enough, and it is likely to introduce memory leak. Surely there must be better way
No, there is no way to disable the garbage collector. There cannot be, because what is Chrome supposed to do when more memory is requested but none is available?
(Also, the garbage collector is very fine-grained and complicated; your screenshot is a bit too small to be readable, but in all likelihood what you're seeing are small steps of incremental work to keep up with allocations, and/or "minor GC" cycles that only operate on the relatively small area of the heap where new allocations happen.)
If you want to reduce time spent in GC, then the primary way how to achieve that is to allocate fewer and/or smaller objects. Yes, that can mean changing your application's design so that objects are reused instead of being short-lived, or similar changes in strategy.
If you allocate a lot, you will see a lot of GC activity, there is just no way around that. This is true even in languages/runtimes that are not considered "garbage collected", e.g. in C/C++ using new/delete a lot also has a performance cost.

What methods are there to prevent the Javascript gc from running as little as possible?

I'm learning Javascript, and in the various texts the authors will speak of javascript using a mark and sweep gc to deallocate objects from memory. They will also speak of how if you set the value a variable references to null it will delete the reference to that value, allowing the allocated space to be set for gc. This SO answer says that you can remove the allocated memory and the reference by setting the value the variable contains to null and then to undefined, effectively removing the allocated space from the heap (if I understood it correctly).
So my question is this: Is it possible to write javascript in such a way that you can eliminate gc?
(If it is implementation specific I would like to know if it is possible on v8, though if this is possible on rhino or other js implementations that would be of immense use too)
Judging by projects like LLJS my request isn't too unreasonable, but I'm not entirely sure how the memory module does it.
I've always found it helpful if I explain why I'm asking so here it goes. I really like compilers, and I wanted to write a compile-to-js language that leveraged a static inferred typing system similar to SML. The reason why I wanted to write my own was because I wanted to utilize region inference to determine exactly when objects and variables come out of scope (as much as possible) and upon leaving scope remove it from the heap, thereby eliminating as much gc as possible. This is mostly a research project (read: because I can) so any resources on memory optimization in javascript would also be greatly appreciated!
EDIT: I guess another way to phrase it would be "Is it possible to write js in such a way that the gc will deterministically never run (as much as possible)? If so what techniques would be involved?"
I'm not looking per se for delete because that marks the element for deletion thereby invoking what I wanted to (try to) avoid, I was curious if the implementation's gc would run if I removed all references (and the value) associated with the variable.
Alternatively, paraphrasing from the referenced SO Answer:
x = foo;
x = null;
x;
Is x still on the heap?
It's not entirely clear what you're looking for.
The standard Javascript implementations have NO way of manually deallocating memory. You can remove a property with the delete operator, but that just removes the property from the object. It doesn't even free any contents that the property points to (that is left for garbage collection if there are no other references to that data).
Javascript was designed from the ground up to be a garbage collected language. It frees things from physical memory only when the garbage collector runs and that garbage collector finds objects that are unreachable (e.g. there are no references to those objects still in use). The language does not contain commands to free memory.
It is possible (in some JS implementations) to call the GC yourself rather than wait for the JS engine to run it, but it's still using GC to decide what to free.
Responding to the additional things you added to your answer.
To the best I know, javascript only cleans things up when the GC runs. Until then objects are marked such that the GC can see that there are no references to them anywhere, but they aren't actually freed until the GC checks and notices this. Further, local variables in a function scope are themselves a type of object and those are not freed until the GC runs and notices that there are no references to the function scope (in JS, a closure can maintain a reference to a function scope even after the function has completed).
So, in your code example:
x = foo; x = null; x;
x is still alive and occupying some space because it's still in scope and code could still reach it. It's contents will be null which presumably takes no extra space beyond the variable itself, but the space for the variable itself won't be freed until the function context it is in is found to be reference free by the garbage collector.
JS is a garbage collected language. That's when things are actually freed from the heap. There are no instructions in the language to free things anytime sooner.
The delete keyword will trigger garbage collection by the browser. Be aware that it deletes entire chains of objects unless you nullify object references.
var o = {...};
delete o;

JQuery Remove and memory leaks

Im working on a game, and ive seen a lot of memory consuption, im using jquery animate, and after the animation is done, i .remove() the element, my question is, after removing an element from the dom tree, the object still exist in memory?
Javascript is a garbage collected language. That means that an object in memory will be released when no code holds any references to it and (for a DOM object) it's not in the DOM. So, when you remove an object from the DOM, as long as no other part of your javascript has a reference to that DOM object, the DOM object will be cleaned up and it's memory returned to the available memory pool when the garbage collector gets a chance to run.
Keep in mind that when memory is freed by the garbage collector, it may not be returned to the system right away or ever. It may stay as memory allocated to the browser, but it will be available for use by other memory requests within the browser. So, freeing memory in your script won't necessarily make the total memory used by the browser go down.
It is only a memory leak if repeatedly carrying out the same operation over and over causes the total memory used by the browser to continually rise. Only then can you be sure that some memory is being permanently consumed by a "leak".
There are a number of nuances about garbage collection, particularly for older versions of IE, but for modern browsers, mostly what you need to keep in mind is that if you hold a reference to an object in your own javascript data structures, it will not be garbage collected. If you don't hold a reference to it and it's not in the DOM, it will be freed and its memory recycled.
If there are no references to the element, garbage collection will clean it up on its next run. You're just fine using .remove, but don't bother worrying about the garbage collection.

Categories

Resources