using UnityEngine; using System; using XLua; public class LuaMemoryLeakCheckerTest : MonoBehaviour { LuaEnv luaenv = new LuaEnv(); Action update; LuaMemoryLeakChecker.Data data = null; void Start() { luaenv.DoString(@" local local_leak = {} global_leak = { a = {}} --global_leak.a.b = global_leak local no_leak = {} function make_leak1() table.insert(local_leak, 1) table.insert(global_leak, {}) end -- 会不断创建并持有新table,但其实没泄漏 function innocent() no_leak.a = {x = 1} no_leak.b = {y = 1} end ", "@leak1.lua"); luaenv.DoString(@" local anthor_leak = {a = {{ b = {}}}} function make_leak2() table.insert(anthor_leak.a[1].b, 1) end local t = 1 slow_global_leak = {} debug.getregistry()['ref_anthor_leak'] = anthor_leak function slow_leak() if t == 40 then t = 0 table.insert(slow_global_leak, {x = 0, y = 1}) else t = t + 1 end end ", "@leak2.lua"); luaenv.DoString(@" shutdown_fast_leak = false function update() if not shutdown_fast_leak then make_leak1() make_leak2() end innocent() slow_leak() end ", "@main.lua"); luaenv.Global.Get("update", out update); data = luaenv.StartMemoryLeakCheck(); Debug.Log("Start, PotentialLeakCount:" + data.PotentialLeakCount); } int tick = 0; bool finished = false; void Update() { if (!finished) { tick++; update(); luaenv.Tick(); if (tick % 30 == 0) { data = luaenv.MemoryLeakCheck(data); Debug.Log("Update, PotentialLeakCount:" + data.PotentialLeakCount); } if (tick % 180 == 0) { Debug.Log(luaenv.MemoryLeakReport(data)); if (tick == 180) { //假装解决了快速内存泄漏 luaenv.Global.Set("shutdown_fast_leak", true); //开启一个新的泄漏检测 data = luaenv.StartMemoryLeakCheck(); } else { finished = true; Debug.Log("Finished"); } } } } void OnDestroy() { update = null; luaenv.Dispose(); } }