Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular referencing in Javascript reference counting

Tags:

javascript

In Nicholas Zakas' book, he explains the problem of circular referencing when using reference counting for garbage collection in Javascript. He uses the following example:

function problem(){
    var objectA = new Object();
    var objectB = new Object();

    objectA.someOtherObject = objectB;
    objectB.anotherObject = objectA;
}

explaining that the two objects will never have the memory allocated to them freed since they have two references to them inside the function. I would like some clarification of how this works.

Clearly, there are two references to each object. The first object has both objectA and objectB.anotherObject pointing to it. The situation is analogous for the second object. So the reference count for each object is 2. But what happens when the function is exited? This isn't really described in the book. He says that the reference count is decremented whenever a reference to the value is overwritten with another value. I think this means:

function problem(){
    var objectA = new Object();
    var objectB = new Object();

    objectA.someOtherObject = objectB;
    objectB.anotherObject = objectA;
    objectA.someOtherObject = objectA; //<-- that if I were to do this, 
                                       //the reference count of the second object (B) 
                                       //would become 1, and 3 for the first object (A). 

}

But what happens when the function exits? As far as I understand, both objectA and objectB and their respective properties that reference each other will be destroyed, and thus, the two objects' reference counts will be decremented by 2. I don't see the "circular reference problem" that Zakas talks about. Could somebody explain what he's trying to say?

like image 363
Sahand Avatar asked Sep 18 '17 14:09

Sahand


2 Answers

As far as I understand, both objectA and objectB and their respective properties that reference each other will be destroyed.

No. The local variables objectA and objectB will be destroyed (because the function scope ends and no closures reference these variables). That means the reference counts in the objects that were referenced by the variables each get decremented by 1.

If the object's reference count was 0, the object would get destroyed and all other things it references would get their count decremented. But the counts of the objects still are 1 each - they still reference each other -, and nothing gets destroyed.

like image 192
Bergi Avatar answered Oct 11 '22 16:10

Bergi


The "problem" with reference counting and "circular" reference comes about when allocated objects contain references to other objects, but are otherwise unreferenced by active allocations. That is, there are cliques in the overall reference graph of items that are not active but which nevertheless contain references to other non-active items.

In your example code, when that function exits there are no active references to the two allocated objects, but the objects reference each other so the reference counts are not 0. The local variables objectA and objectB will disappear at the exit of the function (because the closure is itself garbage, at that point), but the internal references the objects hold keep their reference counts greater than zero.

It's not an unsolvable problem, but it complicates the otherwise simple approach of reference counting as a garbage collection technique.

Note that there's no rule or specification that insists JavaScript implementations use any particular garbage collection technique.

like image 40
Pointy Avatar answered Oct 11 '22 16:10

Pointy