JSBinding / Memory Management (GC)

C# and JavaScript both have Garbage Collection (GC). They should not conflict with each other.

Class type object

Class is reference type. We maintain a Map<> to store one-to-one relationship between C# class object and corresponding JavaScript object.

An example:

// C#
List<int> lst = new List<int>();

// JavaScript (Compiled from C#)
var lst = new System.Collections.Generic.List$1.ctor(System.Int32.ctor);


The process of returning a C# class object to JavaScript is:

1) C# gets JavaScript object ID from JavaScripit.

// File: System_Collections_Generic_List77.javascript
_jstype.definition.ctor = function(t0) { CS.Call(5, 249, 0, true, this, t0.getNativeType()); } // 1) Here, 'this' will be passed to C#,C# wil get an ID (an int value representing JavaScript object)

2) C# creates a List<T> object (T is from JavaScript). See code below, Line14.

// System_Collection_Generic_List77Generated.cs

 1 static bool ListA1_ListA11(JSVCall vc, int argc)
 2 {
 3     int _this = JSApi.getObject((int)JSApi.GetType.Arg); // we have JavaScript object here!
 4     JSApi.attachFinalizerObject(_this); // (4)
 5     --argc;
 6 
 7     ConstructorInfo constructor = JSDataExchangeMgr.makeGenericConstructor(typeof(System.Collections.Generic.List<>), constructorID0); 
 8     if (constructor == null) return true;
 9 
10     int len = argc - 1;
11     if (len == 0)
12     {
13         JSMgr.addJSCSRel(_this, // (3)
14             constructor.Invoke(null, new object[]{})  // (2)
15         );
16     }
17 
18     return true;
19 }

3) C# stores one-to-one relationship. see code above, line 13.

NOTE: we store List<> object, and this object must be removed from map some time later, otherwise it will never be collected by C# GC.

4) Register a C# finalizer callback for JavaScript object, when it is collected by JavaScript GC, C# will be notified, and will remove the one-to-one relationship in C# map. See code above, Line 4.

5) Any time we want to return a C# object to JavaScript, we will first search the map, if corresponding JavaScript already exists, we simply return it. Otherwise we create and return a new JavaScript object. In this example, we already have a JavaScript (Line 3), so we don't need to create a new one.

Summary

for class type object, we will store C# object and JavaScript object relationship to a map. JavaScript object's life cycle is controlled by JavaScript GC, and C# object is removed when that JavaScript is collected.

Value type object (struct)

struct is value type. It's not possible to create a one-to-one relationship.  When we want to return a C# struct to JavaScript, we always create a new one. And the relationship is: it's OK to find C# struct by JavaScript object ID, but it's not possible to find a JavaScript object by C# struct object.

map1[jsObjID] = csObj; // YES
// map2[csObj.hashCode] = jsObjID; // NO

C# object is removed when JavaScript object is collected. (exactly as class object).

原文地址:https://www.cnblogs.com/answerwinner/p/4690752.html