NodeJS require function, that loads modules, has a "cache" (which is a object).
Entries is this cache are garbage collected once I'm no longer using the module? (resulting in loading from disk if used again)
I think the answer is "no", but I didn't found any references on the web
Entries is this cache are garbage collected once I'm no longer using
the module?
No. Modules loaded with require() are cached indefinitely whether you are done using them or not.
Memory for Javascript variables/objects that is used by the module is garbage collected subject to all the normal rules of garbage collection (when there is no live code that still has a reference to the variable/object). But, the module cache keeps a reference to the loaded module itself so the code or any module level variables are not garbage collected unless a module is manually removed from the cache.
Here's a link to the node.js doc on the topic.
Caching
Modules are cached after the first time they are loaded. This
means (among other things) that every call to require('foo') will get
exactly the same object returned, if it would resolve to the same
file.
If you want to manually remove a module from the cache, that is described here:
unloading code/modules
Though, this will allow all module-level variables to be garbage collected, given the way node.js is structured I don't think it will actually unload the code from memory.
Related
When you import a file in nodejs, it's loaded, evaluated and cached.
Is it possible to free the memory for that file, if you know you will never use it again (or maybe in a long time, worth it to compile it again).
What I want to do is importing a temporal file, read its code, execute it once and then free it forever (I know it's not going to be used again, and I don't want to have memory leaks)
Basically is having dynamic code in nodejs.
Pages like codility which allows you to input code and execute in backend side, should work with a similar solution... unless they run a complete new nodejs instance with that code... and then kill it.
Is it possible? If so, how?
You can delete from the module cache like this. Just make sure that there are no circular dependencies or the module will not actually be freed from memory
delete require.cache[require.resolve('./theModuleYouWantToDelete.js')]
It depends what you mean by "free" the module. Nodejs does not have a way to remove the code once it has been run so that will always remain in memory.
If you remove all references to the module (by deleting it from the cache) and removing any other references there might be to exported data, then any data associated with the module should be eligible for garbage collection.
For a service that lets the user run arbitrary code on the server, I would always run that in a sandboxed separate process where you can kill the process and recover all resources used by the code, not run that in the main server process.
Ok, reading the NodeJS documentation about modules, it happens to exist a public cache member and it says:
Modules are cached in this object when they are required. By deleting a key value from this object, the next require will reload the module. This does not apply to native addons, for which reloading will result in an error.
Adding or replacing entries is also possible. This cache is checked before native modules and if a name matching a native module is added to the cache, no require call is going to receive the native module anymore. Use with care!
So I guess every evaluated module lives here internally, and removing a key from this object like the docs says, it will also free the related memory to that portion of code (when the garbage collector do its job)
I have a use case where I repeatedly fetch data from the server and display it using cytoscape. For this, I just have a single cy object and I repeatedly remove and add the elements. This happens once every second or two. I notice the browser memory growing with time. The documentation says "Though the elements specified to this function are removed from the graph, they may still exist in memory"
So, do I need to do anything with the collection returned by calling remove? How do I ensure memory is cleared.
Well javascript is already a garbage collected language, so it will drop all of your references to your nodes eventually. If you remove nodes from the graph and you don't have any references to it, then the garbage collector will clean it up ... eventually :)
Due to the fact that these memory leaks exists, my educated guess is, that there may be some internal entanglement with a global scope or sth like that which prevents elements to be discarded before the whole graph is reinitialized (maybe try that?).
Given a typical structure like the one below, when are the different variables being freed by the garbage collector?:
'Use strict';
var $ = require('jquery');
var somePrivateVar = new Whatever();
module.exports = functions (){
var someInsideVar = new Whatother();
var someOtherInsideVar = $('.myStuf');
$(window).scroll(function(){
somePrivateVar.MoreStuff();
doSomeStuff(someInsideVar);
someOtherInsideVar.toggle();
});
};
EDITED: the proposed another question is related but not the point of this question. I already know a little about garbage collection. I'm not interested in handling the garbage or avoiding it. I'm interested in how nodejs mounts the modules behind the scenes closure-wise. Put in other words, if you like, how nodejs implements those principles in the first response to the other question to handle efficiently the memory.
A module in node.js is simply a closure that stays alive by the same rules that other closures in Javascript would stay alive. As long as any code within the closure is still reachable by other code, then the closure itself can't be garbage collected. And, modules are also cached by the module loader which means a reference to the module is kept alive in the module cache, even if no other code has retained a reference to the module. You may find it helpful to read this article: How require() Actually Works because it is normal Javascript GC of a scope that determines when a given module can be garbage collected or not. There is no special garbage collection for modules.
So, your module variables will be alive as long as this module closure created when the module was loaded stays referenced. While that closure is alive, the only way that contents of the referenced variables within the module would be freed while the module was loaded is if you clear the contents of those variables manually (e.g. setting to null).
By default, a node module remains alive and loaded in the node module cache (waiting for some other code to require() it in again) even if it is no longer currently being used or referenced by the rest of your code. It can be manually removed from the cache if you so choose. See this answer for details on manually removing a module (and perhaps any modules that it also loads) from the cache: Unloading node code/modules. So, if none of your code has a reference to the module, the module has no live event handlers or callbacks in it and you've manually removed the module from the cache, then the module closure should no longer have any reachable code references into it and the GC can free that whole scope (and thus the module).
A module remains alive as long as any code in it is still reachable (e.g. can still be called by any other code). In your case, this would be the case if any other code still has a reference to the module or as long as the event handler in the module is still alive (could still be invoked) because the event handler callback references code within the module. It is not always clear exactly how smart a given garbage collector will be about knowing when a given event handler is done and can never be invoked again in the future.
In your specific example, the $(window).scroll() event handler (which seems like a bit of a made up example because there's usually no window object in node.js that does scrolling) would theoretically be alive forever until you manually removed the event handler with .off() or until the window object itself is deleted or something like that. So, the references inside that event handler would never go away on their own.
Other event handlers that have a specific lifetime such as an Ajax success handler will be done when the ajax call itself has finished executing and all callbacks have been called. Those event handlers will release any references they hold when they are done. Same for a setTimeout(). It will release any reference it holds when it executes (or when the timer is cancelled).
It is often times hard to predict how smart a garbage collector can be and when it will realize that a given variable is no longer reachable and thus can be garbage collected. Some things are easy to understand such as when a variable goes out of scope and no other references remain to the scope so the entire scope will be GCed. But some things are not so simple such as when a scope is still alive because an event handler in that scope is still alive, but nothing in that particular event handler could actually reference a given variable within that scope. Whether or not the GC will actually try to GC a single variable within that scope in that case is implementation dependent. Things like eval() and constructing new Function objects with code built via string manipulation make it very hard for Javascript to know exactly what could and could not be referenced in the future from a given event handler or callback (since it's possible to construct almost any reference programmatically without the interpreter knowing what you "may" reference in the future). This complicates fine grained garbage collection. What you can count on is whole scope garbage collection (when the whole scope is released). Counting on finer grained GC than that it probably not wise. If you are explicity done with a very large variable within a scope that might last a lot longer, then it's safer to just null out that very large variable so its specific reference to the large data is cleared when you want it to be cleared. This wouldn't be significant for a small string (unless you had tens of thousands of these objects), but might be relevant for a large buffer or very large string.
Edit: It does appear that V8 does garbage collection of individual variables within a scope if those variables themselves are not referenced within any of the code that is still reachable within the closure and there are no uses of eval() in that same code. I have not found any authoritative references on the subject, but have verified that this appears to be the case in testing actual situations.
I have an object, which I believe is held only by a WeakReference. I've traced its reference holders using SOS and SOSEX, and both confirm that this is the case (I'm not an SOS expert, so I could be wrong on this point).
The standard explanation of WeakReferences is that the GC ignores them when doing its sweeps. Nonetheless, my object survives an invocation to GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced).
Is it possible for an object that is only referenced with a WeakReference to survive that collection? Is there an even more thorough collection that I can force? Or, should I re-visit my belief that the only references to the object are weak?
Update and Conclusion
The root cause was that there was a reference on the stack that was locking the object. It is unclear why neither SOS nor SOSEX was showing that reference. User error is always a possibility.
In the course of diagnosing the root cause, I did do several experiments that demonstrated that WeakReferences to 2nd generation objects can stick around a surprisingly long time. However, a WRd 2nd gen object will not survive GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced).
As per wikipedia "An object referenced only by weak references is considered unreachable (or "weakly reachable") and so may be collected at any time. Weak references are used to avoid keeping memory referenced by unneeded objects"
I am not sure if your case is about weak references...
Try calling GC.WaitForPendingFinalizers() right after GC.Collect().
Another possible option: don't ever use a WeakReference for any purpose. In the wild, I've only ever seen them used as a mechanism for lowering an application's memory footprint (i.e. a form of caching). As the mighty MSDN says:
Avoid using weak references as an
automatic solution to memory
management problems. Instead, develop
an effective caching policy for
handling your application's objects.
I recommend you to check for the "other" references to the weakly referenced objects. Because, if there is another reference still alive, the objects won't be GCed.
Weakly referenced objects do get removed by garbage collection.
I've had the pleasure of debugging event systems where events were not getting fired... It turned out to be because the subscriber was only weakly referenced and so after some eventual random delay the GC would eventually collect it. At which point the UI stopped updating. :)
Yes it is possible. If the WeakReference is located in another generation than the one being collected, for example, if it is in the 2nd Generation, and the GC only does a Gen 0 collection; it will survive. It should not survive a full 2nd Gen collection that completes and where all finalizers run, however.
What does just-in-time initialization means?
This is "lazy" initialization, i.e. initialization performed only when/if the underlying module or feature is needed for the first time.
The purpose of this practice is to save time and, to a lesser extent, memory or other run-time resources by not loading modules which are not systematically needed in a given session of the application.
It is particularly useful for HTML pages, for which only the essential resources are loaded along with the main page, but all other resources are merely marked with a placeholder in the DOM containing only the necessary info for some [typically] javascript snippet to effectively replace the location so the underlying image or other resource gets loaded, following some action from the user (or also some timer event) when needed. See this article for more info about the use of JITI with web pages
With HTML this makes for faster load of the page, giving the idea of a snappier application because pages load faster.
In Just in time initialization Loads object only when an attribute is get or set or when these fields are accessed.
Non-lazy initialization retrieves an object and all of its related objects at load time.
Just in time initialization increases the performance and effective utilization of resources .
If you are looking for Hibernate Just-in-time initialization check out this document