Sunday, July 13, 2014 at 6:37 AM

JavaScript memory management question

  • First, up front -- I am an experienced language developer and a programmer. So I know about memory management and garbage collection. I've seen lots of different kinds of heaps. And I implemented the garbage collector in Frontier, a runtime environment that has been in use constantly since 1992. #

  • So I don't need an explanation of dynamic languages and memory management.#

  • But I have a question about JavaScript garbage collection. #

  • Here's the scenario#

    • The content management system in Fargo has a stack that manages the attributes of pages as they are rendered, resulting in something called the pagetable. There's scoping in this attribute system. #

    • 1. At the base of the stack are the values that are global to all Fargo users. #

    • 2. Next level up are values that are global to this Fargo user. #

    • 3. Then the values at the top level of the outline containing the document being rendered.#

    • 4. Then each of the levels leading to the document. So you can have values that are local to a given year, month or day, or to a specific post. (These are less common, but you do end up using these too.)#

    • A value at a higher level in the stack overrides a value with same name at a lower level. So I may have set the default background color for all my blogs as whitesmoke, but want it to be yellow for one document. #

    • Because you might render more than one page in a given build, I keep these structs in a global cache, while the rendering is happening, and release them when the rendering is done. #

    • If you're experienced with JavaScript you probably know that it's the last statement that I have questions about. Take as a given that these structures must be global (or attached to the window structure in the browser, same thing). #

    • How can I be confident that I've released them when the build is done?#

  • Specifics#

    • var cmsNodeStackCache = new Array (); #

    • Is the global. It's an array of objects, some quite large. #

    • How can I force all of its storage to be reclaimed?#

    • I don't care if it's reclaimed now or at some time in the future, what I care about is that it is logically empty. When I go look for something in that array, after emptying it, I can be guaranteed that I won't find it. #

    • I have seen behavior that more or less proves that my current method of emptying it is not in fact emptying it. This is what I do:#

    • while (cmsNodeStackCache.length > 0) {cmsNodeStackCache.pop ();}#

    • To Fargo users: This is why values seem to mysteriously "leak" from one website to another. #

  • Idea#

    • I've been reading whatever I can find on the subject and the answer I see most is basically "Dear programmer you have nothing to worry about, just forget about reclaiming your structure, as soon as there are no pointers to it, the JS runtime will do it for you."#

    • That has led me to believe that perhaps the way to do the reclaiming is simply:#

    • cmsNodeStackCache = null;#

    • That way anything in the array will no longer have anything pointing to it, and we can trust the runtime to do the reclaiming? Does this make sense?#

  • Update#

    • I asked Brendan Eich what he thought: "Setting the global to null should work but it is too easy via closure over-capture to leak. Search for JS leak detector devtools."#

Last built: Sun, Mar 22, 2015 at 5:51 PM

By Dave Winer, Sunday, July 13, 2014 at 6:37 AM. What a long strange trip it's been.