sluaunreal icon indicating copy to clipboard operation
sluaunreal copied to clipboard

设置组件位置, 当GC时,分析非常耗时, 导致卡顿

Open gzbin7878at2016 opened this issue 3 years ago • 3 comments

Describe the bug 每帧设置组件的位置代码如下: LuaBpActor.lua添加的测试代码

function actor:ReceiveTick(dt) self:_TestLoc() self:_TestLoc() self:_TestLoc() self:_TestLoc() self:_TestLoc() self:_TestLoc() end

function actor:_TestLoc() self._hit = import("HitResult")() self._loc = import("Vector")() self["bp_Cube"]:K2_SetRelativeLocation(self._loc, false, self._hit, false) end

Version UE4.26 for_4.25

To Reproduce Steps to reproduce the behavior:

  1. 编辑器运行
  2. 开启 stat unitgraph
  3. 等待一分钟, ue gc

log: LogTemp: Error: CollectGarbageInternal bForceSingleThreadedGC=1 GCreateGCClusters=1 numClusters=0 bWithClusters=0 LogGarbage: Error: MarkObjectsAsUnreachable gcIndex=0, MaxNumberOfObjects=24212, NumThreads=14, NumberOfObjectsPerThread=1730, bParallel=0, bWithClusters=0 LogGarbage: Verbose: 0.186300 ms for MarkObjectsAsUnreachable Phase (20100 Objects To Serialize) LogTemp: Error: ObjectsToCollectReferencesFor Num=20100 LogTemp: Error: ProcessObjectArray==start== LogTemp: Error: ProcessObjectArray=CurrentIndex=2580==4== 34.154000 ms, ReferenceInfo.Type=9 LogTemp: Error: ProcessObjectArray=CurrentIndex=2580==2== 34.195400 ms, CurrentObject=000001D0FED0E700, name=GCObjectReferencer_0, fullname=GCObjectReferencer /Engine/Transient.GCObjectReferencer_0 LogTemp: Error: ProcessObjectArray==end== LogGarbage: Verbose: 53.864400 ms for Reachability Analysis LogGarbage: 54.086800 ms for GC

gc 的Reachability Analysis耗时达到34ms, 具体项目中,复杂度更高, 达到80~90ms

Desktop (please complete the following information):

  • OS: windows10, android都会
  • 使用设备htc vive, pico neo3

gzbin7878at2016 avatar Aug 21 '21 07:08 gzbin7878at2016

微信图片_20210821154812

gzbin7878at2016 avatar Aug 21 '21 07:08 gzbin7878at2016

->self._hit = import("HitResult")() ->self._loc = import("Vector")() Tick里构造HitResult与Vector会不断申请临时内存,使用完后就等着GC,所以量会很大,造成卡顿。 profile时看memory usage应该可以验证这一点

如果位置不变,可以预先定义好复用,作为upvalue传入: funciton actor:ReceiveBeginPlay() self._loc = Vector() self._hit = HitResult() end

function actor:_TestLoc() self["bp_Cube"]:K2_SetRelativeLocation(self._loc, false, self._hit, false) end

如果会有变化或者需要设置多个,可以构建Vector/HitResult池或者在上一步基础上传入数值,也可以不在lua构造放到c++去做: 池: funciton actor:ReceiveBeginPlay() for i = 1, num do self._loc[i] = Vector() self._hit[i] = HitResult() end end

传数值: funciton actor:ReceiveBeginPlay() self._loc = Vector() self._hit = HitResult() end

function actor:_TestLoc(x, y, z) self._loc.x = x self._loc.y = y self._loc.z = z self["bp_Cube"]:K2_SetRelativeLocation(self._loc, false, self._hit, false) end

ryanrhu avatar Nov 08 '21 01:11 ryanrhu

每帧设置组件的位置代码如下: LuaBpActor.lua添加的测试代码

是的,import操作很耗时,建议仅需要做一次

pangweiwei avatar Dec 01 '21 08:12 pangweiwei

新版已经有缓存了,现在二次import不影响速度了

zjhongxian avatar Jul 07 '23 01:07 zjhongxian