1

I am writing a networked application that needs to load and unload self-contained (approved) code dynamically. The main goal, in short, is to load these scripts for short amounts of time and avoid global name collisions or contaminating the global scope, and being able to unload them and have everything be garbage collected.

The initial problem was that any global variables will persist after unload if I simply add and remove a script in the DOM.

My temporary solution was to wrap all of my individual dynamic code section files in:

systemArray.push((function() {
// local-global scope
function main() {
   // do something
}
return main;
}()));
...
...
// some external code calls:
systemArray[sandboxIdx](); // max of 10 sandboxes at once, need to unload old sandboxes that have been exited

and simply pop the array upon unload to let the garbage collector do its work. However, this doesn't really allow for splitting the sub-program into multiple files, and it seems a little error-prone unless I can do some preprocessing on the server-side to create a concatenated file.

Then I looked into ES6 modules. These seem to be fine and avoid name collisions, but it's unclear to me whether modules can ever be unloaded, which is the key thing that I need to do without changing webpages or refreshing.

Firstly, is there a way to unload a module explicitly at runtime? The main, non-unloading part of the application only needs to import one function, but the scripts themselves may have a lot of code. Secondly, if the answer is yes, do any modules that the unloaded module load also get unloaded? Are global variables within the modules correctly garbage collected? If the answer is no, what other options are there?

synchronizer
  • 1,955
  • 1
  • 14
  • 37
  • `I am writing a Node JS application /.../ I simply add and remove a script in the DOM.`. The DOM is not a concept in NodeJS. Can you please clarify if you're running the code in the browser or in NodeJS. – Olian04 Aug 24 '19 at 23:41
  • I meant it’s a networked application with a server-side component using NodeJS, but you’re right, that part is irrelevant. I meant ES6 client-side code. @Olian04 – synchronizer Aug 24 '19 at 23:47
  • why do you want to unload modules? – Olian04 Aug 24 '19 at 23:55
  • The idea is that my application is a host for trusted user code that we cycle through. They’re all isolated “worlds”/game loops. But we need to exit those “worlds” and never see them again. There could be MANY of them. I want to clear the user code/memory every time we switch to another one because we don’t care about keeping the user code around. We also have struct memory and global scope requirements. I realize this may seem arbitrary, but it’s part of a project with those constraints and goals. I hope what I would like to do is in fact doable with the modules instead of the hacky solution. – synchronizer Aug 25 '19 at 00:01
  • @Olian04 I found this unanswered question that is equivalent to mine—has anything changed? It seems as though unloading is impossible. https://stackoverflow.com/questions/50284661/garbage-collect-unused-modules – synchronizer Aug 25 '19 at 16:34
  • 1
    This does seem like a flaw in the design or implementation of dynamic loading. It defeats the purpose of splitting a large front-end application into modules for better memory management. We do get the benefit of deferred loading, which might speed up bootstrap time, but as the user navigates around different areas of the application the memory use will grow. This was a solved problem in the days of Flash:(https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Loader.html#unload()), it's a shame browser module systems don't seem to enable this. – Tim Stewart Sep 17 '19 at 23:44
  • @TimStewart Is there an avenue for proposing an update to the standard so as to improve the situation? – synchronizer Sep 18 '19 at 16:23

0 Answers0