Unity 2019.1.14f1的内存泄漏问题
(先声明下:本文章所有用到的图片,只为了学习和研究用途,未经我同意,不得进行转载或者其他用途)不知道是不是Unity的bug, 没找到有人问,但是我们自己build出来的exe,运行的时候就内存飞涨,只是一个简单的UI界面。
先用unity的本身的profiler和memory profiler查看,发现内存没有变化,Editor运行着查看,内存也没有变化,说明泄漏的东西unity本身并没有去抓取到,而且Editor里面是已经处理好的,
那么就是别的plugin的东西或者是d3d底层的创建的东西,因为unity对Texture2d, RT, mesh等等他能抓的都在memoryprofiler已经有体现了。
用vmmap和windbg都看了下,vmmap下看到heap不停的有16192k大小的被分配出来,里面是260k,4k...很多,基本你等半个小时,可以从资源管理器中看到内存是按g在增长的,用windbg可以看到某4个大小的块的数量在飞快增加。
然后用vmmap看了下堆栈,发现是从unityplayer.dll到d3d11里面的,但具体哪里看不到,初步怀疑是CreateBuffer的问题
用MTuner挂上pdb,可以看到这个。
然后看Unity这里关于Buffer管理的地方,可以找到RenderBufferManager.cpp这个,我们用的都从这里分配和释放以及缓冲,不知道为啥unity没有把这个加到memoryprofiler里面。
他这个RenderBufferManager 里面,其实管理了2个,一个是Textures,另外一个就是Buffers, 我们主要看下Buffers的管理
对外的接口也是非常简单的,
这个函数就是每帧更新的函数,但是它只在Editor里面调用到
这里有个特殊的函数,DelayedRelease(),这个函数有什么用呢
这里就要看ReleaseTempBuffer
,释放的时候,后面有带一个参数,就是让这个Buffer要延迟几帧释放,默认是直接放到了他的m_FreeBuffers中,
但是如果大于0,则会放到m_DelayedReleaseLists数组中(有1,2,3,4四个),而DelayedRelease()这个函数的作用,就是每帧去看当前要去释放m_DelayedReleaseLists的哪个数组里的buffer,把它放到m_FreeBuffers中,
m_FreeBuffers是最终的cache,GarbageCollect 函数回去最终的回收,即 GetGfxDevice().DeleteBuffer 。
所以这里看了一圈,就有问题了
1.这个m_DelayedReleaseLists 到底为了啥用途,因为GetTempBuffer 也是从m_FreeBuffers里拿的,和它没关系,它的存在感觉就是临时存放了下,延迟回收,如果外面有要求的话
2.为什么只有Editor调用了FrameUpdate, Player Runtime的时候没有调用
那我们看下Runtime的时候调用了啥,可以看到Player.cpp文件
它注册了EarlyUpdate的回调,但是这里只是调用了GarbageCollect()函数,但是没有地方调用DelayedRelease(),那放到m_DelayedReleaseLists里面的东西怎么办,只能等到RenderBufferManger.Cleanup的时候被调用到,才被释放资源。
所以如果有大量调用ReleaseTempBuffer函数,而且带了参数的,那就会导致大量的泄漏的产生。
我们来看下哪里会调用,其实调用的地方真的很少,就2个
往上找调用,可以看到
所以,大家可以看到为啥一直在涨了。
然后对比了一下2019.3的代码,发现
全部消失了,干净了。。。。。。。。。。。。。
应该也是内部同事看不下去了吗??
解决办法:
见我上面的修改,调用他的FrameUpdate函数就可以了,然后重新build unity。
(先声明下:本文章所有用到的图片,只为了学习和研究用途,未经我同意,不得进行转载或者其他用途)
页:
[1]