From b0cd3feda1bc7a91c7d378a50bdd1b81a7af00b0 Mon Sep 17 00:00:00 2001 From: jarjin <2338894521@qq.com> Date: Sat, 28 Nov 2015 19:05:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B8=85=E7=90=86=E7=BA=B9?= =?UTF-8?q?=E7=90=86=E5=BC=95=E7=94=A8=E9=81=97=E7=95=99BUG=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/uLua/Core/MethodWrapper.cs | 40 ++++++++++++++++++++++++++-- Assets/uLua/Core/ObjectTranslator.cs | 9 +++++-- ReadMe.txt | 3 +++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Assets/uLua/Core/MethodWrapper.cs b/Assets/uLua/Core/MethodWrapper.cs index 6615b7e..ec2c282 100644 --- a/Assets/uLua/Core/MethodWrapper.cs +++ b/Assets/uLua/Core/MethodWrapper.cs @@ -1,4 +1,4 @@ -namespace LuaInterface +namespace LuaInterface { using System; using System.IO; @@ -35,7 +35,9 @@ public MethodBase cachedMethod public bool IsReturnVoid; - // List or arguments + // List or arguments, + // fjs: 狗日的这个会缓存每一次调用某个函数的参数,导致内存释放不了。 + // 修改方案: 调用完成后,或中间出错退出时一定要清空这个数组的所有元素, 完事以后一定得提起裤子就走人,别留恋! public object[] args; // Positions of out parameters public int[] outList; @@ -132,6 +134,15 @@ private static bool IsInteger(double x) { return Math.Ceiling(x) == x; } + // fjs: 清空缓存的 args 数组,否则这里会造成内存泄露,无法被GC掉, 纹理内存最严重 + private void ClearCachedArgs() + { + if(_LastCalledMethod.args == null) { return ; } + for(int i = 0; i < _LastCalledMethod.args.Length; i++) + { + _LastCalledMethod.args[i] = null; + } + } /* * Calls the method. Receives the arguments from the Lua stack @@ -170,6 +181,7 @@ public int call(IntPtr luaState) if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) throw new LuaException("Lua stack overflow"); + // fjs: 这里 args 只是将 _LastCalledMethod.args 拿来做缓冲区用,避免内存再分配, 里面的值是可以干掉的 object[] args = _LastCalledMethod.args; try @@ -247,6 +259,7 @@ public int call(IntPtr luaState) MethodBase m = (MethodInfo)member; + // fjs: 这里在缓存调用参数,退出前一定要释放掉 bool isMethod = _Translator.matchParameters(luaState, m, ref _LastCalledMethod); if (isMethod) { @@ -262,6 +275,10 @@ public int call(IntPtr luaState) LuaDLL.luaL_error(luaState, msg); LuaDLL.lua_pushnil(luaState); + + // fjs: 这里释放掉缓存的参数对象 + ClearCachedArgs(); + return 1; } } @@ -271,6 +288,7 @@ public int call(IntPtr luaState) if (methodToCall.ContainsGenericParameters) { // bool isMethod = //* not used + // fjs: 这里在缓存调用参数,退出前一定要释放掉 _Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod); if (methodToCall.IsGenericMethodDefinition) @@ -290,6 +308,9 @@ public int call(IntPtr luaState) { LuaDLL.luaL_error(luaState, "unable to invoke method on generic class as the current method is an open generic method"); LuaDLL.lua_pushnil(luaState); + + // fjs: 这里释放掉缓存的参数对象 + ClearCachedArgs(); return 1; } } @@ -301,10 +322,14 @@ public int call(IntPtr luaState) LuaDLL.lua_remove(luaState, 1); // Pops the receiver } + // fjs: 这里在缓存调用参数,退出前一定要释放掉 if (!_Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod)) { LuaDLL.luaL_error(luaState, "invalid arguments to method call"); LuaDLL.lua_pushnil(luaState); + + // fjs: 这里释放掉缓存的参数对象 + ClearCachedArgs(); return 1; } } @@ -313,7 +338,11 @@ public int call(IntPtr luaState) if (failedCall) { if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) + { + // fjs: 这里释放掉缓存的参数对象 + ClearCachedArgs(); throw new LuaException("Lua stack overflow"); + } try { if (isStatic) @@ -330,10 +359,14 @@ public int call(IntPtr luaState) } catch (TargetInvocationException e) { + // fjs: 这里释放掉缓存的参数对象 + ClearCachedArgs(); return SetPendingException(e.GetBaseException()); } catch (Exception e) { + // fjs: 这里释放掉缓存的参数对象 + ClearCachedArgs(); return SetPendingException(e); } } @@ -355,6 +388,9 @@ public int call(IntPtr luaState) nReturnValues++; } + // fjs: 这里释放掉缓存的参数对象 + ClearCachedArgs(); + return nReturnValues < 1 ? 1 : nReturnValues; } } diff --git a/Assets/uLua/Core/ObjectTranslator.cs b/Assets/uLua/Core/ObjectTranslator.cs index 1afb0d9..6196ef9 100644 --- a/Assets/uLua/Core/ObjectTranslator.cs +++ b/Assets/uLua/Core/ObjectTranslator.cs @@ -6,8 +6,15 @@ namespace LuaInterface using System.Reflection; using System.Runtime.InteropServices; using System.Collections.Generic; + using UnityEngine; //using System.Diagnostics; + public static class ObjectExtends { + public static object RefObject(this object obj) { + return new WeakReference(obj).Target; + } + } + /* * Passes objects from the CLR to Lua and vice-versa * @@ -632,7 +639,6 @@ public void pushObject(IntPtr luaState, object o, string metatable) int index = -1; // Object already in the list of Lua objects? Push the stored reference. bool beValueType = o.GetType().IsValueType; - if (!beValueType && objectsBackMap.TryGetValue(o, out index)) { if (LuaDLL.tolua_pushudata(luaState, weakTableRef, index)) @@ -648,7 +654,6 @@ public void pushObject(IntPtr luaState, object o, string metatable) // Remove from both our tables and fall out to get a new ID collectObject(o, index); } - index = addObject(o, beValueType); pushNewObject(luaState, o, index, metatable); } diff --git a/ReadMe.txt b/ReadMe.txt index e01803c..9c4ae2d 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -12,6 +12,9 @@ 游戏案例地址 http://www.ulua.org/showcase.html 框架详细介绍 http://doc.ulua.org/default.asp?cateID=4 +//-------------2015-11-28------------- +(1)修复清理纹理引用遗留BUG。 + //-------------2015-11-10------------- (1)添加lua中使用self关键字例子A6_LuaCall