Skip to content

Instantly share code, notes, and snippets.

@secf4ult
Created September 11, 2019 16:46
Show Gist options
  • Save secf4ult/97fbe11201b52d820afae6790679c092 to your computer and use it in GitHub Desktop.
Save secf4ult/97fbe11201b52d820afae6790679c092 to your computer and use it in GitHub Desktop.
The memory leak meteor bumped into.
// From the Meteor blog: https://blog.meteor.com/an-interesting-kind-of-javascript-memory-leak-8b47d2e7f156.
// TL;DR
// If a variable is used by a closure, it ends up in the lexical enviroment shared by all closures in that scope,
// which can lead to memory leaks.
// Even though function unused is never called, originalThing is refered in its body, so originalThing is shared
// by the lexical environment between unused and someMethod, which is also a closure, so someMethod holding the
// lexical environment prevents the originalThing from being GCed, because it's important that all closures in
// that scope get the same variable.
// This can be fixed in the JS engine if each closure has its own lexical environment (a dictionary containing
// only the viriables which it actually reads and writes) instead of sharing a common one.
// For now, this can be fixed by nullifying the variable.
// example 1
var theThing = null
var replaceThing = function () {
var originalThing = theThing
var unused = function () {
if (originalThing)
console.log("hi")
}
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage)
}
}
// can be fixed by adding
// originalThing = null
}
setInterval(replaceThing, 1000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment