【U3D性能优化教程——Mono内存篇】之五:Unity19最新功能:Incremental Garbage Collection(全网首发)

 

 

 

本文由@唐三十胖子出品,转载请注明出处。  
文章链接:https://blog.csdn.net/iceSony/article/details/86306080

 

 

 

这篇文章由唐三胖ヾ(•ω•`)o网络整理总结,针对Mono概念的系列优化教程。

【U3D性能优化教程——Mono内存篇】之五:Unity19最新功能:Incremental Garbage Collection(全网首发)_第1张图片

通过这篇文章,你可以知道

1)最新的GC回收机制

1.背景介绍

在Unity19版本前,Unity使用的GC工作模式为:检查引用->停止正在运行的程序->进行垃圾回收

在不同性能的平台上,这可能会造成肉眼可见的卡顿。为了解决这一问题,在Unity19版本新增了增量垃圾回收(Incremental Garbage Collection

 

使用的仍然是原本的GC收集器,但将原本单帧回收拆分成多帧处理,从而降低卡顿感。

【U3D性能优化教程——Mono内存篇】之五:Unity19最新功能:Incremental Garbage Collection(全网首发)_第2张图片

                                                                          图1.官方未开启下30ms的峰值

 

【U3D性能优化教程——Mono内存篇】之五:Unity19最新功能:Incremental Garbage Collection(全网首发)_第3张图片

                                                                         图2.官方开启后的曲线图

2.功能原理

This is because we adjust the time allotted to the GC based on the remaining available frame time if Vsync or Application.targetFrameRate is being used. This way, we can run the GC in time which would otherwise be spent waiting, and thus get GC “for free”.

Specifically, when incremental GC breaks up its work, the part which it breaks up is the marking phase, in which it scans all managed objects to find which other objects they reference, to track which objects are still in use. This assumes that most of the references between objects don’t change between slices of work.

Also, when using incremental GC, Unity needs to generate additional code (known as write barriers) to inform the GC whenever a reference has changed (so the GC will know if it needs to rescan an object). This adds some overhead when changing references which can have a measurable performance impact in some managed code.
    事实上,当游戏限制Application.targetFrameRate帧率以后,增量GC会根据剩余可用帧时间调整分配给GC的时间。这样,我们可以及时运行GC,而不是浪费时间等待,从而“免费”获得GC。

具体来说,当增量GC分解其工作时,它分解的部分是标记阶段,其中它扫描所有管理对象以查找它们引用的其他对象,以跟踪哪些对象仍在使用中。这假设对象之间的大多数引用不会在工作片之间发生变化。

此外,在使用增量GC时,Unity需要生成额外的代码(称为写屏障),以便在引用发生更改时通知GC(因此GC将知道是否需要重新扫描对象)。

3.开启方式

Edit->Project Settings中开启选项

【U3D性能优化教程——Mono内存篇】之五:Unity19最新功能:Incremental Garbage Collection(全网首发)_第4张图片

                                                                                         图3.开启选项

 

官方测试使用为Mac版本,实测在Windows编辑器模式下勾选Use incremental GC依然不会生效,增量回收也无法开启测试,需Build之后才能看到结果。

4.测试用例

测试代码

void Update()

{

    string str = "now num is :";

    for (int i = 0; i < 500; i++)

    {

        str += i + "   ";

    }

    Debug.Log(str);

}

点击按钮触发

btn2.onClick.AddListener(() => {

    string str = "now num is :";

    for (int i = 0; i < 2000; i++)

    {

        str += i + "   ";

    }

    Debug.Log(str);

});

你可以很明显的看出平均GC回收时长增加了,但是峰值得到了极大的改善

【U3D性能优化教程——Mono内存篇】之五:Unity19最新功能:Incremental Garbage Collection(全网首发)_第5张图片

                                                                          图4.未开启下的回收时长

【U3D性能优化教程——Mono内存篇】之五:Unity19最新功能:Incremental Garbage Collection(全网首发)_第6张图片

                                                                                       图5开启下的回收时长

测试用例当中是这样的帧率

【U3D性能优化教程——Mono内存篇】之五:Unity19最新功能:Incremental Garbage Collection(全网首发)_第7张图片

                                                                             图6开启后帧率会有所降低

5.潜在风险

1.测试不完全,需要平台支持

2.由于分帧检测引用对象,具体来说,当增量GC分解其工作时,它分解的部分是标记阶段,其中它扫描所有管理对象以查找它们引用的其他对象,以跟踪哪些对象仍在使用中。这假设对象之间的大多数引用不会在工作片之间发生变化。当它们发生变化时,需要在下一次迭代中再次扫描已更改的对象。这可能导致增量收集永远不会完成的情况,因为它总是会添加更多工作 - 在这种情况下,GC将回退到执行完整的非增量收集。

3.使用增量GC本身有性能消耗:需要生成额外的代码(称为写屏障),以便在引用发生更改时通知GC(因此GC将知道是否需要重新扫描对象)。

4.事实上,创建人工测试用例很容易一直在更改所有引用,其中增量GC的性能比非增量GC差。需在实际项目中测试。

6.功能总结

可以优化GC峰值,但取而代之是一种常驻的消耗。

直接的表现是帧率的降低,这点在官方博客上没有提及。

而且增量GC回收勾选以后没法通过代码关闭,也就是说消耗会一直存在。

谨慎开启:)

你可能感兴趣的:(U3D开发性能优化,【U3D性能优化教程】)