在 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; 博士
谢谢你的帮助!
最佳答案
我在 Unity answers 上发布了同样的问题并得到了回复:
https://answers.unity.com/questions/1535588/is-there-a-way-to-accurately-measure-heap-allocati.html
不,基本上是不可能的。您可以在循环中多次运行单元测试,并希望它产生足够的垃圾来导致 GC.GetTotalMemory() 返回的值发生变化,但仅此而已。
关于unity3d - 有没有办法在 Unity 中准确测量堆分配以进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51579982/