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 Cycle
A 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 cycle
Silk 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.