Memory Management
In Silk, Reference counting is
used to manage objects memory, and the object will be deallocated
when the reference counts is 0, so nomally we do not need to care about
the Memory Management.
But we may have a risk which will leak memory
when a Reference Cycle is created. So we need to avoid creating
Reference Cycle when we use the objects(Array,Dictionary, Class).
Reference CycleA reference cycle means one or more objects referencing each other.
For
example: A refers to B, B refers to C, and C
refers back to A, the following code will create a reference cycle, and
leak memory:
A={"value":1};
B={"value":2};
C={"value":3};
A["next"]=B;//the 'next' in A refers to B
B["next"]=C;//the 'next' in B refers to C
C["next"]=A;//the 'next' in C refers to A, create an A->B->C->A cycle
An object that refers to itself will also create reference cycle:
main()
{
arr=[];
arr.append(arr);//will create a reference cycle
}
Dealing with reference cycleSilk provides the weak reference functions
_getptr() and
_restore(ptr) as a solution to avoid reference cycle.
_getptr() will return the handle of the object(the reference in memory), but will not increase the reference counts.
_restore(ptr) will restore the object with the handle.
So we can use these 2 functions to break the cycle:
main()
{
A={"value":1};
B={"value":2};
C={"value":3};
A["next"]=B;//the 'next' in A refers to B
B["next"]=C;//the 'next' in B refers to C
C["next"]=A._getptr();//the 'next' in C refers to the handle of A, so will not create reference cycle
a=C._restore(C["next"]);//restore A with the handle in C next
print(a["value"]);//print the value in A
arr=[];
arr.append(arr._getptr());//add the handle instead of object itself.
}
The
above code forms a cycle, but not a reference cycle, so the objects A,
B, C and arr will be deallocated successfully when they are no longer
needed.