ECMAScript 6 introduces weak maps, available in Node.JS v0.11.3 with the --harmony
flag. Consider the following.
let weakMap = WeakMap();
let key = [];
let rubbish = 'fish cans';
weakMap.set(key, rubbish);
rubbish = 'empty bottle';
// Prints "fish cans"
console.log(weakMap.get(key));
I was under the impression that, for weak maps, the reference from the key to the value is weak, so that if the only reference to the value is the key, then the value can no longer be accessed.
Why then is the value 'fish cans'
still accessible and not garbage collected? The variable rubbish
no longer references it, and the reference from key
to 'fish cans'
is weak, i.e. non-existant from the point of view of the garbage collector. What am I missing?
WeakMap. A Map is an unordered list of key-value pairs where the key and the value can be of any type like string, boolean, number, etc. In a Weak Map, every key can only be an object and function. It used to store weak object references.
WeakMap is Map -like collection that allows only objects as keys and removes them together with associated value once they become inaccessible by other means. WeakSet is Set -like collection that stores only objects and removes them once they become inaccessible by other means.
WeakMaps allows you to store a collection of Key-Value pairs. It adopts the same properties of Map. The Major difference is that keys of WeakMap cannot be a primitive data type. The keys must be of type object and values can be of any data type.
WeakSet in JavaScript is used to store a collection of objects. It adapts the same properties of that of a set i.e. does not store duplicates. The major difference of a WeakSet with the set is that a WeakSet is a collection of objects and not values of some particular type.
The weak part is about the keys, not the values. From the current draft:
WeakMap are intended to provide a mechanism for dynamically associating state with an object in a manner that does not “leak” memory resources if, in the absence of the WeakMap, the object otherwise became inaccessible and subject to resource reclamation by the implementation’s garbage collection mechanisms.
Say you have a DOM element and want to associate some data with it and use a WeakMap
for that: weakMap.set(domElement, data);
. When the DOM element gets deleted then the entry in the weak map gets deleted too.
On the other hand you would not want the data to be deleted as long the DOM element exists, just because there is no other reference to it outside the weak map.
Apart from that 'fish cans'
is a primitive type and as such not subject to the garbage collection.
Why then is the value
'fish cans'
still accessible and not garbage collected? The variable rubbish no longer references it, and the reference from key to'fish cans'
is weak, i.e. non-existant from the point of view of the garbage collector. What am I missing?
The variable rubbish
never was the one that needed to reference it. The association (reference) from the key to the value still exists as long as the key is not collected. The weak reference, which the GC cannot see, is the one from the map to the key/value pair (the one which would make the map enumerable). Yet your key
still exists, and you can get every value that you stored for it in the map:
var map = WeakMap(),
key = [];
map.set(key, 'fish cans');
console.log(map.get(key)); // Prints "fish cans"
To demonstrate the weakness, you'd have to use the following:
var map = WeakMap(),
key = [];
map.set(key, 'fish cans');
// map.size == 1
key = null;
// map.size == 0 - the fish cans got garbage-collected together with the key
map.get(???) // impossible now
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With