Closed BlurryLight closed 1 year ago
过滤UWorld比较丑而且也没解决问题:我记得持有场景的任意待销毁对象都会有同样的问题。 我觉得较合理的做法是:首先业务得保证自己切场景前在js不持有场景上的对象(你举的argv,puerts有问题,也要修改下,执行玩Start脚本后应该清理argv对象);然后执行下js虚拟机的gc。
感觉只要在js里获得过EditorWorld 且 JsEnv不是随用随弃的情况下都会有问题。
比如这样的情况,切地图就会崩
// cpp
UWorld* UToolBPLibrary::GetEditorWorld()
{
for (auto& It: GEngine->GetWorldContexts())
{
UWorld* World = It.World();
if(!World) continue;
if(World->WorldType == EWorldType::Editor)
{
return World;
}
}
return GWorld;
}
// QuickStart.js
import * as UE from 'ue'
UE.ToolBPLibrary.GetEditorWorld()
切地图前你试试进行一次全量的js gc,JsEnv上的LowMemoryNotification(只是告知,v8的gc不一定会执行Full gc),RequestFullGarbageCollectionForTesting
手动调用FullGC后可以解决问题,会通过FJsEnvImpl::UnBind
释放引用。
前置阅读 | Pre-reading
Puer的版本 | Puer Version
1.0.5
UE的版本 | UE Version
All
发生在哪个平台 | Platform
Editor(win)
错误信息 | Error Message
问题重现 | Bug reproduce
一个最简单可复现的例子。 JSEnv是外部保存的某个
SharedPtr
,把当前的EditorWorld传给ts时,会触发JsEnv::UserObjectRetainer::Retain
,将这个UWorld添加一次引用。在这种情况下切地图,虚幻会crash,因为当前EditorWorld被JsEnv引用着。项目里实际碰见的情况比这个复杂一点,但是原因是一样的: 某些函数调用可能返回了EditorWorld。
一个简单的修复是在
FObjectRetainer::Retain
的时候排除UWorld对象。