Is there any possibility to execute some custom js code when some object instance is going to be collected by GC in IE9? Maybe DOM nodes can afford this functionality somehow?
I'm trying to build some interop library and need to find a way of controlling object instances lifetimes...
Not to the best of my knowledge. But you can fake it.
One approach is to manually implement a disposal method on each of your JavaScript objects, and have each object dispose all of its members when it is disposed. It does mean you'll have disposed object instance shells lying around before garbage collection, but as long as you're diligent about disposing instances it gives you reasonable resource management.
Related
I've read a number of questions that state it is unwise to add properties to DOM element objects; and they seem to make a great deal of sense. The best suggestion I came across to accomplish the same end was to use a Weak Map with the DOM node reference as the key.
That led me to wonder about adding properties to function objects. Is that "safe" to do or should another object or map be used for this also. I'm referring to functions on the window object. Can the property names I add clash with names in the function object in the future?
That brings up a related matter I've been trying to understand which is that some claim that the window object is so cluttered up that it ought not to be added to and scripts should be modules now. Modules appears to be more isolated than my limited experience with simple namespaces. Is there anything to be gained through using scripts of type module over just declaring another object and making your functions methods of that object? That object would still be added to the window object.
Thank you.
That led me to wonder about adding properties to function objects. Is that "safe" to do or should another object or map be used for this also. I'm referring to functions on the window object. Can the property names I add clash with names in the function object in the future?
It's not safe in that, if you do it, others could do it too. For example:
// Your code
RegExp.description = 'some description for the constructor!';
setTimeout(() => {
console.log(RegExp.description);
});
// Someone else's code
RegExp.description = "someone else's description";
The only consolation is that it's pretty unlikely for such a thing to happen.
Similarly, it's pretty unlikely for some random English word that one library creates for itself on the window collides with another word that another library creates for itself on the window - but it's not impossible. For that reason
That object would still be added to the window object.
can be seen as slightly less than optimal on huge pages, where collisions are a real possibility.
Is there anything to be gained through using scripts of type module over just declaring another object and making your functions methods of that object?
Yes, see above. If all of your code is in module scripts, there should be no need to put any object onto the window, in most cases. In addition to the above, module scripts often make projects easier to manage because they make all dependencies explicit through the use of import statements. They're also very easily integrated into a build process like Webpack - and build processes allow for all sorts of neat things that aren't easily done otherwise.
When using Rust in a browser, I can get JavaScript objects and use them inside Rust (using, for instance, the js! macro from the stdweb library).
Given that these objects came from JavaScript, can I use them in Rust to implement structures that benefit from garbage collection (for instance, to implement graphs)?
It depends on cost of JS<>Wasm interaction, and the way you're going to use the data.
To get definitive answer you'd have to try a specific algorithm and benchmark it, but in general I don't expect it to be beneficial.
For complex object graphs in Rust you'd use Rc<RefCell<…>>. It has a relatively low overhead, so you'd need to have very GC-friendly usage pattern to beat it, especially given overhead of JS objects.
In Javascript I'm iterating through an array of UNIDs and getting a NotesDocument by UNID, then I do a doc.remove(true);
having done that is it necessary to do a doc.recycle()?
Short answer is yes.
For newbies, Notes objects in Java consist of a Java object and a reference to a C++ object. So when you a Java object becomes null (or useless), garbage collector will clear the memory space after a certain amount of time. However, the C++ handle will persist. So we are recycling notes objects to destroy C++ object references. This page has a good explanation abouyt recycling.
On the other hand, doc.remove() can be thought as a state change. Moreover, if soft deletion is enabled in your database, it won't even remove the document, will just mark as deleted (you have to call .removePermanently() to hard-delete it). The C++ object reference will stay in the memory.
Therefore, remove method will not trigger a recycle for the object. Recycle is only triggerred by the object itself or its parent.
I believe you should still recycle it. It's an object at that point not a document.
I don't know too much about the JavaScript garbage collector, just that it attempts to manage references so that unreferenced objects can be periodically purged from memory. I was thinking about something that I thought might improve performance if it was feasible by the language implementers.
It would go something like this. In a file add a line:
"no gc";
This is similar to the use strict setting. It would mark everything defined in the file as not for garbage collection. I'm thinking this would be used in libraries like jQuery and underscore. All of the helper methods would be marked and stored in a separate area of memory that is not managed by the GC.
While I know this might end up keeping around stuff that is not ever used; it would at least isolate it from periodic GC process. So while we perhaps gobble up some extra memory, we at least lighten the load of GC processing.
I apologize for the naivety of this suggestion as I have never implemented GC. I am just wondering if this idea is feasible or if JavaScript somehow does this already.
if you want to keep them as cache then you have global scope.
In browser global scope is window,
hence consider if you dont want object X to never get garbage collected then simply you can write
window.nogc = X;
since window which is global scoped ,will be never garbage collected so its child references also wont be garbage colleted until we explicitly make it.
Garbage collection only runs when the thread is free. Nothing would be saved because GC only occurs when the system isn't busy.
So no, this isn't possible.
You can ensure that an object does not get collected by referencing it from a GC root, but not that it doesn't get processed by the GC.
The reason is that GC in JS VMs is usually implemented via Mark-and-Sweep, or a method that is functionally equivalent. The basic premise is that the GC goes through a cycle that goes like this:
The GC marks all objects in the heap as being "potentially available for release". This is usually done by a flag toggle which changes the interpretation of the existing marks on objects from meaning "need to keep" to "safe to release". So no actual iteration over the objects occurs at this stage. Telling the GC to "not mark" certain objects would actually require extra operations, not less.
The GC starts at the GC roots, and traverse through the reference tree, changing the mark of objects from "safe to release" to "need to keep". This is the "Mark" phase. GC roots can be global objects, the currently executing stack, pending callbacks on the event loop, etc. The tree-traversal itself can be done in various way as well, with DFS being the simplest.
The GC goes over all objects in the heap, and removes any that is still marked "safe to release". This is the "Sweep" phase. Many optimizations exist in this phase, which allows the GC to free memory used by a group of objects in a single operation. Nevertheless, this requires at least some level of iteration, over groups of objects, if not over objects themselves.
Now here's the issue with setting a "non-GC" arena: Suppose that an object in your "non-GC" arena was to reference a regular object. During the "Mark" phase, if that object is not marked, it would be released. That means that all of your "non-collectible" objects need to be GC roots in order to "keep" regular objects to which they refer. And being a GC root offers no performance advantage over being directly referenced by a GC root. Both must equally participate in the "Mark" phase.
The only alternative is for your non-collectible object to not be able to strongly reference collectible objects at all. This can be achieved by having your own binary heap, rather than using native JS objects. The binary data would not be interpreted as references, and the heap object would finish its marking phase in a single operation. This is what asm.js does: It preallocates a large array to act as its internal heap. To the VM, the entire array counts as one big object, and therefore no garbage collection is done on any data structures that are encoded within it. Using this method does have the flaw that you need to encode all of your objects and data structures into the heap's binary format, and decode them when you want to use them. When working with asm.js, this is handled by the compiler.
in JavaScript if you want to kill a object, you have to delete all the references.
let's say we have a object like this:
var myobj={ obj : {} };
and we want to GC the obj object, we have to do this:
myobj["obj"] = null;
delete myobj["obj"];
but if you define another variable referenced to that object, it won't be killed with those line. for instance if you do:
var obj = myobj.obj;
if you really want to delete the object, you have do the same for this variable:
obj = null;
delete obj;
then if there is no reference it would be killed.
in other word if you want to prevent your object from GC, create a reference some where and keep it private.
I was hoping to find out any information on practices to optimize for garbage collection or prevent object's from building up in memory over time.
As an example, let's say I have a continuous iteration and each time an item is added to an object.
Over time, older items added to the object are no longer relevant for the application, and should be removed from the object, they will never again be accessed. Is it necessary to specifically remove these values or would it continue to just build up into a huge object?
Thank you!
If it's your business logic that is dictating their uselessness, meaning there are still references to them, then Yes! You should explicitly remove these objects. In many cases you will want to wipe the object before breaking the references to ensure you're releasing everything you intend to release.
Ashley over at Scirra wrote a good primer on this earlier this year: How to write low garbage real-time Javascript