Esempio n. 1
0
    public static void ShutdownJSEngine()
    {
        shutDown = true;

        /*
         * 在 Shutdown 时,先主动删除 CSRepresentedObject
         * 现在已经没有必要再维护 id -> CSR.. 的关系了
         * 移除后,CSR.. 有可能还被其他地方引用,所以在这个函数中调用C# GC,也不一定会调用到 CSR.. 的析构
         * 后来在某个时刻析构被调用,在析构函数里有  removeJSCSRel ,那里会判断 round 是上一轮的所以忽略
         */
        List <int> keysToRemove  = new List <int>();
        List <int> hashsToRemove = new List <int>();

        foreach (var KV in mDictionary1)
        {
            JS_CS_Rel rel = KV.Value;
            if (rel.csObj is WeakReference)
            {
                if ((rel.csObj as WeakReference).Target is CSRepresentedObject)
                {
                    keysToRemove.Add(KV.Key);
                    hashsToRemove.Add(rel.hash);
                }
            }
        }
        foreach (var k in keysToRemove)
        {
            mDictionary1.Remove(k);
        }
        foreach (var h in hashsToRemove)
        {
            mDictionary2.Remove(h);
        }

        //
        // 并GC
        //
        System.GC.Collect();

        int Count = mDictionary1.Count;


        // There is a JS_GC called inside JSApi.ShutdownJSEngine
#if UNITY_EDITOR
        // DO NOT really cleanup everything, because we wanna start again
        JSApi.ShutdownJSEngine(0);
#else
        JSApi.ShutdownJSEngine(1);
#endif

        StringBuilder sb = new StringBuilder();
        sb.AppendLine("After JSApi.ShutdownJSEngine: ");
        sb.Append("mDictionary1 count " + Count + " -> " + mDictionary1.Count + ", left elements(should only contain JSComponent):\n");

        /*
         * 到这里 mDictionary1 和 mDictionary2 应该只剩余 JSComponent 及其子类,原因是:
         * 除了 JSComponent 外,其他东西都应该在 JSApi.ShutdownJSEngine(0) 后被移除(他里面调用了 JS_GC)
         * 而 JSComponent 是没有垃圾回收回调的,他是在 OnDestroy 时从这2个字典里移除的
         * 这时候可能他的 OnDestroy 还没有执行,所以这2个字典里还会有他们
         */
        List <int> Keys = new List <int>(mDictionary1.Keys);
        foreach (var K in Keys)
        {
            if (!mDictionary1.ContainsKey(K))
            {
                continue;
            }

            JS_CS_Rel Rel = mDictionary1[K];
            sb.AppendLine(K.ToString() + " " + Rel.name);
        }
        Debug.Log(sb);

        allCallbackInfo.Clear();
        JSMgr.MoveJSCSRel2Old();
        mDictJSFun1.Clear();
        mDictJSFun2.Clear();
        evaluatedScript.Clear();
        CSRepresentedObject.s_objCount = 0;
        CSRepresentedObject.s_funCount = 0;
        jsEngineRound++;
    }
Esempio n. 2
0
    public static void ShutdownJSEngine()
    {
        shutDown = true;

        //
        // remove CSRepresentedObject first
        // no need to maintain id -> CSRepresentedObject now
        //
        // after remove, CSRepresentedObject may still be referenced, and ~CSRepresentedObject may not be called
        // some times later ~CSRepresentedObject is called -> removeJSCSRel -> round is ignored because it is last round
        //
        List <int> keysToRemove  = new List <int>();
        List <int> hashsToRemove = new List <int>();

        foreach (var KV in mDictionary1)
        {
            JS_CS_Rel rel = KV.Value;
            if (rel.csObj is WeakReference)
            {
                if ((rel.csObj as WeakReference).Target is CSRepresentedObject)
                {
                    keysToRemove.Add(KV.Key);
                    hashsToRemove.Add(rel.hash);
                }
            }
        }
        foreach (var k in keysToRemove)
        {
            mDictionary1.Remove(k);
        }
        foreach (var h in hashsToRemove)
        {
            mDictionary2.Remove(h);
        }

        System.GC.Collect();

        int Count = mDictionary1.Count;


        // There is a JS_GC called inside JSApi.ShutdownJSEngine
#if UNITY_EDITOR
        // DO NOT really cleanup everything, because we wanna start again
        JSApi.ShutdownJSEngine(0);
#else
        JSApi.ShutdownJSEngine(1);
#endif

        StringBuilder sb = new StringBuilder();
        sb.AppendLine("After JSApi.ShutdownJSEngine: ");
        sb.Append("mDictionary1 count " + Count + " -> " + mDictionary1.Count + ", left elements(should only contain JSComponent):\n");
        //
        // here, mDictionary1 and mDictionary2 should only contain JSComponent and his subclasses, because:
        // everything should be removed after JSApi.ShutdownJSEngine(0) (it calls calls JS_GC)
        // JSComponent is nomally be removed during OnDestroy, but his OnDestroy may not be called yet here
        //
        List <int> Keys = new List <int>(mDictionary1.Keys);
        foreach (var K in Keys)
        {
            if (!mDictionary1.ContainsKey(K))
            {
                continue;
            }

            JS_CS_Rel Rel = mDictionary1[K];
            sb.AppendLine(K.ToString() + " " + Rel.name);
        }
        Debug.Log(sb);

        allCallbackInfo.Clear();
        JSMgr.MoveJSCSRel2Old();
        mDictJSFun1.Clear();
        mDictJSFun2.Clear();
        evaluatedScript.Clear();
        CSRepresentedObject.s_objCount = 0;
        CSRepresentedObject.s_funCount = 0;
        jsEngineRound++;
    }