asqbtcupid / unreal.lua

lua solution for UnrealEngine4
MIT License
300 stars 98 forks source link

4.21下unreal.lua的master版的内存管理bug? #37

Closed ttaw closed 5 years ago

ttaw commented 5 years ago

操作如下: 1.使用master分支的例子工程,用ue4.21生成c++工程,build后打开uproject工程。 2.在content下git/TopDownCharacter蓝图的BeginPlay事件中添加setlifespan(10.f)节点将角色生命周期设为10秒。 3.pie中播放,等待50秒至5分钟左右,有较大几率发现 输出日志 窗口出现错误;如果此时没有出现,点击停止按钮,则几乎必然在输出日志中出现错误。示例错误如下:

LogUObjectArray: Warning: Empty slot LogOutputDevice: Warning: Script Stack (0 frames): LogStats: FPlatformStackWalk::StackWalkAndDump - 5.871 s LogOutputDevice: Error: === Handled ensure: === LogOutputDevice: Error: Ensure condition failed: 0 [File:D:\work\Unreal\LuaPlugin\origin\unreal.lua.4.21_20190206\unreal.lua\Plugins\UnrealLua\LuaPlugin\Source\LuaPluginRuntime\TableUtil.cpp] [Line: 962] LogOutputDevice: Error: Bug LogOutputDevice: Error: Stack: LogOutputDevice: Error: [Callstack] 0x00007ffb9b47c9d9 UE4Editor-LuaPluginRuntime.dll!touobject() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\unreallua\luaplugin\source\luapluginruntime\tableutil.cpp:962] LogOutputDevice: Error: [Callstack] 0x00007ffb9b43f703 UE4Editor-LuaPluginRuntime.dll!EnsureDestroy() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\unreallua\luaplugin\source\luapluginruntime\nativeluafunc.h:695] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54bd97 UE4Editor-Lua53.dll!luaD_precall() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\ldo.c:437] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54b6bf UE4Editor-Lua53.dll!luaD_callnoyield() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\ldo.c:509] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54c0a5 UE4Editor-Lua53.dll!luaD_rawrunprotected() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\ldo.c:145] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54b940 UE4Editor-Lua53.dll!luaD_pcall() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\ldo.c:729] LogOutputDevice: Error: [Callstack] 0x00007ffb9b542551 UE4Editor-Lua53.dll!lua_pcallk() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\lapi.c:968] LogOutputDevice: Error: [Callstack] 0x00007ffb9b47d168 UE4Editor-LuaPluginRuntime.dll!uobjcet_gcfunc() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\unreallua\luaplugin\source\luapluginruntime\nativeluafunc.h:614] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54bd97 UE4Editor-Lua53.dll!luaD_precall() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\ldo.c:437] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54b6bf UE4Editor-Lua53.dll!luaD_callnoyield() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\ldo.c:509] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54c0a5 UE4Editor-Lua53.dll!luaD_rawrunprotected() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\ldo.c:145] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54b940 UE4Editor-Lua53.dll!luaD_pcall() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\ldo.c:729] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54ec3f UE4Editor-Lua53.dll!runafewfinalizers() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\lgc.c:848] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54debd UE4Editor-Lua53.dll!luaC_runtilstate() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\lgc.c:1106] LogOutputDevice: Error: [Callstack] 0x00007ffb9b54dbff UE4Editor-Lua53.dll!luaC_fullgc() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\lgc.c:1173] LogOutputDevice: Error: [Callstack] 0x00007ffb9b541d27 UE4Editor-Lua53.dll!lua_gc() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\lua53\source\lua53\private\lapi.c:1103] LogOutputDevice: Error: [Callstack] 0x00007ffb9b481609 UE4Editor-LuaPluginRuntime.dll!LuaContext::OnWorldCleanup() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\unreallua\luaplugin\source\luapluginruntime\unrealluainterface.cpp:184] LogOutputDevice: Error: [Callstack] 0x00007ffb9b4816b4 UE4Editor-LuaPluginRuntime.dll!LuaContextMgr::OnWorldCleanup() [d:\work\unreal\luaplugin\origin\unreal.lua.4.21_20190206\unreal.lua\plugins\unreallua\luaplugin\source\luapluginruntime\unrealluainterface.cpp:343] LogOutputDevice: Error: [Callstack] 0x00007ffb9b47f00e UE4Editor-LuaPluginRuntime.dll!TBaseRawMethodDelegateInstance<0,LuaContextMgr,void __cdecl(UWorld ,bool,bool)>::ExecuteIfSafe() [d:\work\unreal\standard\ue4\ue_4.21\engine\source\runtime\core\public\delegates\delegateinstancesimpl.h:518] LogOutputDevice: Error: [Callstack] 0x00007ffba9318deb UE4Editor-Engine.dll!TBaseMulticastDelegate<void,UWorld ptr64,bool,bool>::Broadcast() [d:\build++ue4\sync\engine\source\runtime\core\public\delegates\delegatesignatureimpl.inl:974] LogOutputDevice: Error: [Callstack] 0x00007ffba9320780 UE4Editor-Engine.dll!UWorld::CleanupWorld() [d:\build++ue4\sync\engine\source\runtime\engine\private\world.cpp:3762] LogOutputDevice: Error: [Callstack] 0x00007ffbab58af82 UE4Editor-UnrealEd.dll!UEditorEngine::TeardownPlaySession() [d:\build++ue4\sync\engine\source\editor\unrealed\private\playlevel.cpp:748] LogOutputDevice: Error: [Callstack] 0x00007ffbab550f1b UE4Editor-UnrealEd.dll!UEditorEngine::EndPlayMap() [d:\build++ue4\sync\engine\source\editor\unrealed\private\playlevel.cpp:324] LogOutputDevice: Error: [Callstack] 0x00007ffbaaf83002 UE4Editor-UnrealEd.dll!UEditorEngine::Tick() [d:\build++ue4\sync\engine\source\editor\unrealed\private\editorengine.cpp:1992] LogOutputDevice: Error: [Callstack] 0x00007ffbab8a2346 UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick() [d:\build++ue4\sync\engine\source\editor\unrealed\private\unrealedengine.cpp:403] LogOutputDevice: Error: [Callstack] 0x00007ff63f176225 UE4Editor.exe!FEngineLoop::Tick() [d:\build++ue4\sync\engine\source\runtime\launch\private\launchengineloop.cpp:3699] LogOutputDevice: Error: [Callstack] 0x00007ff63f18596c UE4Editor.exe!GuardedMain() [d:\build++ue4\sync\engine\source\runtime\launch\private\launch.cpp:174] LogOutputDevice: Error: [Callstack] 0x00007ff63f1859ea UE4Editor.exe!GuardedMainWrapper() [d:\build++ue4\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:145] LogOutputDevice: Error: [Callstack] 0x00007ff63f1948da UE4Editor.exe!WinMain() [d:\build++ue4\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:276] LogOutputDevice: Error: [Callstack] 0x00007ff63f19659a UE4Editor.exe!scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:283] LogOutputDevice: Error: [Callstack] 0x00007ffc0d7a7e94 KERNEL32.DLL!UnknownFunction [] LogOutputDevice: Error: [Callstack] 0x00007ffc0fcaa251 ntdll.dll!UnknownFunction [] LogStats: SubmitErrorReport - 0.000 s LogStats: SendNewReport - 1.127 s LogStats: FDebug::EnsureFailed - 7.005 s LogOutputDevice: Warning: stack traceback: [C]: in ? [C]: in ? LogUObjectArray: Warning: Other object in slot LogOutputDevice: Warning: Script Stack (0 frames): LogStats: FPlatformStackWalk::StackWalkAndDump - 0.005 s

这样的错误有好几种,有时候提示Other object in slot,有时候提示什么not registered,有时候显示lua堆栈在TimerMgr类的Tick函数中。看提示像是lua的内存管理上的bug。有时间的话能否处理一下这个问题?非常感谢。

asqbtcupid commented 5 years ago

你按~呼出控制台,输入 r.Lua.CheckActorRef 1 ,是不是就没这个问题了?

asqbtcupid commented 5 years ago

这个版本默认Lua里对Actor是弱引用,也就是r.Lua.CheckActorRef默认是0,结果就是Actor被销毁了并且被UE4垃圾回收了之后,Lua触发自己的GC时,使用这个被完全销毁了的Actor导致的一句报错,其实把这句报错注释掉也可以,不影响什么,就是TableUtil.cpp的962行。

我现在改回了默认对Actor是强引用,这要求使用者很好地管理Lua对Actor的引用,如果切地图时Lua还引用着旧地图的Actor,那就会触发UE4的一个check而崩溃,先临时改一下。

ttaw commented 5 years ago

改了后真的没问题了,谢谢。不过,最后一段话没看懂。强引用情况下,应该只会内存无法释放吧,会导致崩溃吗?

asqbtcupid commented 5 years ago

这是UE4的机制,切地图要保证旧地图清理干净,考虑一下Actor会对World有引用,某个Actor没有释放会导致整个world都无法释放,这势必会带来严重的内存问题,所以不如直接崩溃让开发者意识到这点。不过默认情况下,c++这边对Actor都是弱引用的。

ttaw commented 5 years ago

好的,谢谢。