mozilla Mozilla Developer Network

  1. MDN
  2. Web technology For developers
  3. JavaScript
  4. Memory Management

Your Search Results

Memory Management

In This Article

  1. Introduction
  2. Memory life cycle
  3. Allocation in JavaScript
  4. Value initialization
  5. Allocation via function calls
  6. Using values
  7. Release when the memory is not needed anymore
  8. Garbage collection
  9. References
  10. Reference-counting garbage collection
  11. Example
  12. Limitation: cycles
  13. Real-life example
  14. Mark-and-sweep algorithm
  15. Cycles are not a problem anymore
  16. Limitation: objects need to be made explicitly unreachable
  17. See also

Introduction

Low-level languages, like C, have low-level memory management primitives like malloc() and free(). On the other hand, JavaScript values are allocated when things (objects, strings, etc.) are created and “automatically” freed when they are not used anymore. The latter process is called garbage collection. This “automatically” is a source of confusion and gives JavaScript (and high-level languages) developers the impression they can decide not to care about memory management. This is a mistake.

Memory life cycle

Regardless of the programming language, memory life cycle is pretty much always the same:

  1. Allocate the memory you need
  2. Use the allocated memory (read, write)
  3. Release the allocated memory when it is not needed anymore

The first and second parts are explicit in all languages. The last part is explicit in low-level languages, but is mostly implicit in high-level languages like JavaScript.

Allocation in JavaScript

Value initialization

In order not to bother the programmer with allocations, JavaScript does it alongside with declaring values.

var n = 123; // allocates memory for a number
var s = "azerty"; // allocates memory for a string
var o = {
  a: 1,
  b: null
}; // allocates memory for an object and contained values
// (like object) allocates memory for the array and
// contained values
var a = [1, null, "abra"];
function f(a){
  return a + 2;
} // allocates a function (which is a callable object)
// function expressions also allocate an object
someElement.addEventListener('click', function(){
  someElement.style.backgroundColor = 'blue';
}, false);

Allocation via function calls

Some function calls result in object allocation.

var d = new Date(); // allocates a Date object
var e = document.createElement('div'); // allocates a DOM element

Some methods allocate new values or objects:

var s = "azerty";
var s2 = s.substr(0, 3); // s2 is a new string
// Since strings are immutable value,
// JavaScript may decide to not allocate memory,
// but just store the [0, 3] range.
var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2);
// new array with 4 elements being
// the concatenation of a and a2 elements

Using values

Using value basically means reading and writing in allocated memory. This can be done by reading or writing the value of a variable or an object property or even passing an argument to a function.

Release when the memory is not needed anymore

Most of memory management issues come at this phase. The hardest task here is to find when “the allocated memory is not needed any longer”. It often requires for the developer to determine where in the program such piece of memory is not needed anymore and free it.

High-level languages embed a piece of software called “garbage collector” whose job is to track memory allocation and use in order to find when a piece of allocated memory is not needed any longer in which case, it will automatically free it. This process is an approximation since the general problem of knowing whether some piece of memory is needed is undecidable (can’t be solved by an algorithm).

Garbage collection

As stated above the general problem of automatically finding whether some memory “is not needed anymore” is undecidable. As a consequence, garbage collections implement a restriction of a solution to the general problem. This section will explain the necessary notions to understand the main garbage collection algorithms and their limitations.

References

The main notion garbage collection algorithms rely on is the notion of reference. Within the context of memory management, an object is said to reference another object if the former has an access to the latter (either implicitly or explicitly). For instance, a JavaScript object has a reference to its prototype (implicit reference) and to its properties values (explicit reference).

In this context, the notion of “object” is extended to something broader than regular JavaScript objects and also contains function scopes (or the global lexical scope).

Reference-counting garbage collection

This is the most naive garbage collection algorithm. This algorithm reduces the definition of “an object is not needed anymore” to “an object has no other object referencing to it”. An object is considered garbage collectable if there is zero reference pointing at this object.

Example

var o = {
  a: {
    b:2
  }
};
// 2 objects are created. One is referenced by the other as one of its properties.
// The other is referenced by virtue of being assigned to the 'o' variable.
// Obviously, none can be garbage-collected
var o2 = o; // the 'o2' variable is the second thing that
            // has a reference to the object
o = 1;      // now, the object that was originally in 'o' has a unique reference
            // embodied by the 'o2' variable
var oa = o2.a; // reference to 'a' property of the object.
               // This object has now 2 references: one as a property,
               // the other as the 'oa' variable
o2 = "yo"; // The object that was originally in 'o' has now zero
           // references to it. It can be garbage-collected.
           // However what was its 'a' property is still referenced by
           // the 'oa' variable, so it cannot be freed
oa = null; // what was the 'a' property of the object originally in o
           // has zero references to it. It can be garbage collected.

Limitation: cycles

There is a limitation when it comes to cycles. In the following example two objects are created and reference one another – thus creating a cycle. They will not get out of the function scope after the function call, so they are effectively useless and could be freed. However, the reference-counting algorithm considers that since each of both object is referenced at least once, none can be garbage-collected.

function f(){
  var o = {};
  var o2 = {};
  o.a = o2; // o references o2
  o2.a = o; // o2 references o
  return "azerty";
}
f();

Real-life example

Internet Explorer 6 and 7 are known to have reference-counting garbage collectors for DOM objects. Cycles are a common mistake that can generate memory leaks:

var div;
window.onload = function(){
  div = document.getElementById("myDivElement");
  div.circularReference = div;
  div.lotsOfData = new Array(10000).join("*");
};

In the above example, the DOM element “myDivElement” has a circular reference to itself in the “circularReference” property. If the property is not explicitly removed or nulled, a reference-counting garbage collector will always have at least one reference intact and will keep the DOM element in memory even if it was removed from the DOM tree. If the DOM element holds lots of data (illustrated in the above example with the “lotsOfData” property), the memory consumed by this data will never be released.

Mark-and-sweep algorithm

This algorithm reduces the definition of “an object is not needed anymore” to “an object is unreachable”.

This algorithm assumes the knowledge of a set of objects called roots (In JavaScript, the root is the global object). Periodically, the garbage-collector will start from these roots, find all objects that are referenced from these roots, then all objects referenced from these, etc. Starting from the roots, the garbage collector will thus find all reachable objects and collect all non-reachable objects.

This algorithm is better than the previous one since “an object has zero reference” leads to this object being unreachable. The opposite is not true as we have seen with cycles.

As of 2012, all modern browsers ship a mark-and-sweep garbage-collector. All improvements made in the field of JavaScript garbage collection (generational/incremental/concurrent/parallel garbage collection) over the last few years are implementation improvements of this algorithm, but not improvements over the garbage collection algorithm itself nor its reduction of the definition of when “an object is not needed anymore”.

Cycles are not a problem anymore

In the first above example, after the function call returns, the 2 objects are not referenced anymore by something reachable from the global object. Consequently, they will be found unreachable by the garbage collector.

The same thing goes with the second example. Once the div and its handler are made unreachable from the roots, they can both be garbage-collected despite referencing each other.

Limitation: objects need to be made explicitly unreachable

Although this is marked as a limitation, it is one that is rarely reached in practice which is why no one usually cares that much about garbage collection.

See also

Document Tags and Contributors

Tags:

Contributors to this page:lleaff, rudolfo, beytek, jontejada, mbjordan, ronyeh, fscholz, mishra, macinnir, RogerPoon, xfq, bigperm, anirudh_venkatesh, Agamemnus, velvel53, hectorsan68, Nick_Pershin, Sheppy, RichardC, ethertank, maxatwork, iskitz, dbruant Last updated by:lleaff, <time>Aug 1, 2016, 1:06:43 PM</time> See also

  1. JavaScript
  2. Tutorials:
  3. JavaScript Guide
  4. Introduction
  5. Grammar and types
  6. Control flow and error handling
  7. Loops and iteration
  8. Functions
  9. Expressions and operators
  10. Numbers and dates
  11. Text formatting
  12. Regular expressions
  13. Indexed collections
  14. Keyed collections
  15. Working with objects
  16. Details of the object model
  17. Iterators and generators
  18. Meta programming
  19. Introductory
  20. JavaScript basics
  21. JavaScript technologies overview
  22. Introduction to Object Oriented JavaScript
  23. Intermediate
  24. A re-introduction to JavaScript
  25. JavaScript data structures
  26. Equality comparisons and sameness
  27. Closures
  28. Advanced
  29. Inheritance and the prototype chain
  30. Strict mode
  31. JavaScript typed arrays
  32. SIMD types
  33. Memory Management
  34. Concurrency model and Event Loop
  35. References:
  36. Built-in objects
  37. Array
  38. ArrayBuffer
  39. Atomics
  40. Boolean
  41. DataView
  42. Date
  43. Error
  44. EvalError
  45. Float32Array
  46. Float64Array
  47. Function
  48. Generator
  49. GeneratorFunction
  50. Infinity
  51. Int16Array
  52. Int32Array
  53. Int8Array
  54. [InternalError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError “The InternalError object indicates an error that occurred internally in the JavaScript engine. For example: “InternalError: too much recursion”.”)
  55. Intl
  56. Intl.Collator
  57. Intl.DateTimeFormat
  58. Intl.NumberFormat
  59. Iterator
  60. JSON
  61. Map
  62. Math
  63. NaN
  64. Number
  65. Object
  66. ParallelArray
  67. Promise
  68. Proxy
  69. RangeError
  70. ReferenceError
  71. Reflect
  72. RegExp
  73. [SIMD](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SIMD “SIMD (pronounced “sim-dee”) is short for Single Instruction/Multiple Data which is one classification of computer architectures. SIMD operations perform the same computation on multiple data points resulting in data level parallelism and thus performance gains, for example for 3D graphics and video processing, physics simulations or cryptography, and other domains.”)
  74. SIMD.Bool16x8
  75. SIMD.Bool32x4
  76. SIMD.Bool64x2
  77. SIMD.Bool8x16
  78. SIMD.Float32x4
  79. SIMD.Float64x2
  80. SIMD.Int16x8
  81. SIMD.Int32x4
  82. SIMD.Int8x16
  83. SIMD.Uint16x8
  84. SIMD.Uint32x4
  85. SIMD.Uint8x16
  86. Set
  87. SharedArrayBuffer
  88. StopIteration
  89. String
  90. Symbol
  91. SyntaxError
  92. TypeError
  93. TypedArray
  94. URIError
  95. Uint16Array
  96. Uint32Array
  97. Uint8Array
  98. Uint8ClampedArray
  99. WeakMap
  100. WeakSet
  101. decodeURI()
  102. decodeURIComponent()
  103. [encodeURI()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI “The encodeURI() function encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two “surrogate” characters).”)
  104. [encodeURIComponent()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent “The encodeURIComponent() function encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two “surrogate” characters).”)
  105. escape()
  106. eval()
  107. isFinite()
  108. isNaN()
  109. null
  110. parseFloat()
  111. parseInt()
  112. undefined
  113. unescape()
  114. uneval()
  115. Array.from()
  116. Array.isArray()
  117. [Array.observe()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/observe “The Array.observe() method was used for asynchronously observing changes to Arrays, similar to Object.observe() for objects. It provided a stream of changes in order of occurrence. It’s equivalent to Object.observe() invoked with the accept type list [“add”, “update”, “delete”, “splice”]. However, this API has been deprecated and removed from Browsers. You can use the more general Proxy object instead.”)
  118. Array.of()
  119. Array.prototype
  120. Array.prototype.concat()
  121. Array.prototype.copyWithin()
  122. Array.prototype.entries()
  123. Array.prototype.every()
  124. Array.prototype.fill()
  125. Array.prototype.filter()
  126. Array.prototype.find()
  127. Array.prototype.findIndex()
  128. Array.prototype.forEach()
  129. Array.prototype.includes()
  130. Array.prototype.indexOf()
  131. Array.prototype.join()
  132. Array.prototype.keys()
  133. Array.prototype.lastIndexOf()
  134. Array.prototype.map()
  135. Array.prototype.pop()
  136. Array.prototype.push()
  137. Array.prototype.reduce()
  138. Array.prototype.reduceRight()
  139. Array.prototype.reverse()
  140. Array.prototype.shift()
  141. Array.prototype.slice()
  142. Array.prototype.some()
  143. Array.prototype.sort()
  144. Array.prototype.splice()
  145. [Array.prototype.toLocaleString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString “The toLocaleString() method returns a string representing the elements of the array. The elements are converted to Strings using their toLocaleString methods and these Strings are separated by a locale-specific String (such as a comma “,”).”)
  146. Array.prototype.toSource()
  147. Array.prototype.toString()
  148. Array.prototype.unshift()
  149. Array.prototype.values()
  150. [Array.prototype@@iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@iterator “The initial value of the @@iterator property is the same function object as the initial value of the values() property.”)
  151. Array.prototype[@@unscopables]
  152. Array.unobserve()
  153. array.length
  154. get Array[@@species]
  155. Expressions & operators
  156. Arithmetic operators
  157. Array comprehensions
  158. Assignment operators
  159. Bitwise operators
  160. Comma operator
  161. Comparison operators
  162. Conditional (ternary) Operator
  163. Destructuring assignment
  164. Expression closures
  165. Generator comprehensions
  166. Grouping operator
  167. Legacy generator function expression
  168. Logical Operators
  169. Object initializer
  170. Operator precedence
  171. Property accessors
  172. Spread operator
  173. class expression
  174. delete operator
  175. function expression
  176. function* expression
  177. in operator
  178. instanceof
  179. new operator
  180. new.target
  181. super
  182. this
  183. typeof
  184. void operator
  185. yield
  186. yield*
  187. Statements & declarations
  188. Legacy generator function
  189. block
  190. break
  191. class
  192. const
  193. continue
  194. debugger
  195. default
  196. do…while
  197. empty
  198. export
  199. for
  200. for each…in
  201. for…in
  202. for…of
  203. function
  204. function*
  205. if…else
  206. import
  207. label
  208. let
  209. return
  210. switch
  211. throw
  212. try…catch
  213. var
  214. while
  215. with
  216. Functions
  217. Arguments object
  218. Arrow functions
  219. Default parameters
  220. Method definitions
  221. Rest parameters
  222. getter
  223. setter
  224. arguments.callee
  225. arguments.caller
  226. arguments.length
  227. [arguments@@iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/@@iterator “The initial value of the @@iterator property is the same function object as the initial value of the Array.prototype.values property.”)
  228. Classes
  229. constructor
  230. extends
  231. static
  232. Errors
  233. Error: Permission denied to access property “x”
  234. InternalError: too much recursion
  235. RangeError: argument is not a valid code point
  236. RangeError: invalid array length
  237. RangeError: precision is out of range
  238. RangeError: radix must be an integer
  239. RangeError: repeat count must be less than infinity
  240. RangeError: repeat count must be non-negative
  241. ReferenceError: “x” is not defined
  242. ReferenceError: assignment to undeclared variable “x”
  243. ReferenceError: deprecated caller or arguments usage
  244. ReferenceError: invalid assignment left-hand side
  245. ReferenceError: reference to undefined property “x”
  246. SyntaxError: “x” is not a legal ECMA-262 octal constant
  247. SyntaxError: JSON.parse: bad parsing
  248. SyntaxError: Malformed formal parameter
  249. SyntaxError: Unexpected token
  250. SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
  251. SyntaxError: missing ) after argument list
  252. SyntaxError: missing ; before statement
  253. [SyntaxError: missing ] after element list](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Missing_bracket_after_list “SyntaxError.”)
  254. SyntaxError: missing } after property list
  255. SyntaxError: redeclaration of formal parameter “x”
  256. SyntaxError: return not in function
  257. SyntaxError: test for equality (==) mistyped as assignment (=)?
  258. SyntaxError: unterminated string literal
  259. TypeError: “x” has no properties
  260. TypeError: “x” is (not) “y”
  261. TypeError: “x” is not a constructor
  262. TypeError: “x” is not a function
  263. TypeError: “x” is read-only
  264. TypeError: More arguments needed
  265. TypeError: invalid Array.prototype.sort argument
  266. TypeError: property “x” is non-configurable and can’t be deleted
  267. TypeError: variable “x” redeclares argument
  268. Warning: -file- is being assigned a //# sourceMappingURL, but already has one
  269. Warning: unreachable code after return statement
  270. Misc
  271. Lexical grammar
  272. JavaScript data structures
  273. Enumerability and ownership of properties
  274. Iteration protocols
  275. Strict mode
  276. Transitioning to strict mode
  277. Template literals
  278. Deprecated features
  279. New in JavaScript
  280. ECMAScript 5 support in Mozilla
  281. [ECMAScript 6 support in Mozilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla “ECMAScript 2015 (6th Edition) is the current version of the ECMAScript Language Specification standard. Commonly referred to as “ES6”, it defines the standard for the JavaScript implementation in SpiderMonkey, the engine used in Firefox and other Mozilla applications.”)
  282. ECMAScript Next support in Mozilla
  283. Firefox JavaScript changelog
  284. [New in JavaScript 1.1](https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/1.1 “The following is a changelog for JavaScript from Netscape Navigator 2.0 to 3.0. The old Netscape documentation references this as “Features added after version 1”. Netscape Navigator 3.0 was released on August 19, 1996. Netscape Navigator 3.0 was the second major version of the browser with JavaScript support.”)
  285. New in JavaScript 1.2
  286. New in JavaScript 1.3
  287. New in JavaScript 1.4
  288. New in JavaScript 1.5
  289. New in JavaScript 1.6
  290. New in JavaScript 1.7
  291. New in JavaScript 1.8
  292. New in JavaScript 1.8.1
  293. New in JavaScript 1.8.5
  294. Documentation:
  295. Useful lists
  296. All pages index
  297. Methods index
  298. Properties index
  299. Pages tagged “JavaScript”
  300. Contribute
  301. JavaScript doc status
  302. The MDN project

© 2005-2016 Mozilla Developer Network and individual contributors.

Content is available under these licenses.