有没有办法在Unity中准确测量堆分配以进行单元测试?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有没有办法在Unity中准确测量堆分配以进行单元测试?相关的知识,希望对你有一定的参考价值。
在Unity中每一帧在堆上分配临时对象都是昂贵的,我们都尽力通过缓存堆对象和避免垃圾生成功能来避免这种情况。虽然有些东西会产生垃圾,但这并不总是很明显。例如:
enum MyEnum {
Zero,
One,
Two
}
List<MyEnum> MyList = new List<MyEnum>();
MyList.Contains(MyEnum.Zero); // Generates garbage
MyList.Contains()生成垃圾,因为List的默认相等比较器使用objects
,这导致枚举值类型的装箱。
为了防止像这样的无意堆分配,我希望能够在我的单元测试中检测它们。
我认为这有两个要求:
- 一个函数返回堆分配的内存量
- 一种防止在测试期间发生垃圾收集的方法
我还没有找到一个干净的方法来确保#2。我发现#1最接近的是GC.GetTotalMemory()
[UnityTest]
IEnumerator MyTest()
{
long before = GC.GetTotalMemory(false);
const int numObjects = 1;
for (int i = 0 ; i < numObjects; ++i)
{
System.Version v = new System.Version();
}
long after = GC.GetTotalMemory(false);
Assert.That(before == after);
}
问题是GC.GetTotalMemory()在此测试之前和之后返回相同的值。我怀疑Unity / Mono只分配来自系统堆的内存,比如4kb,所以你需要在Unity / Mono实际上从系统堆请求更多内存之前分配<= 4kb,此时GC.GetTotalMemory()将返回不同的值。我确认如果我将numObjects更改为1000,GC.GetTotalMemory()会返回之前和之后的不同值。
总而言之,1。如何准确地获取堆分配内存的数量,精确到字节和2.垃圾收集器可以在我的测试体内运行,如果是这样,是否有任何非hacky方式禁用GC在我的测试期间
TL; DR感谢您的帮助!
我在Unity答案上发布了同样的问题并得到了答复:
https://answers.unity.com/questions/1535588/is-there-a-way-to-accurately-measure-heap-allocati.html
不,基本上不可能。您可以在循环中多次运行单元测试,并希望它生成足够的垃圾以导致GC.GetTotalMemory()返回的值发生更改,但这就是它。
以上是关于有没有办法在Unity中准确测量堆分配以进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章