版本:Unity 6 (6000.0)
语言英语
  • C#

Profiler.GetTotalFragmentationInfo

提出更改建议

成功!

感谢您协助提高 Unity 文档的质量。尽管我们无法接受所有提交,但我们确实会阅读用户提出的每项更改建议,并在适用情况下进行更新。

关闭

提交失败

由于某些原因,无法提交您建议的更改。请在几分钟后<a>重试</a>。感谢您腾出宝贵时间帮助我们提高 Unity 文档的质量。

关闭

取消

声明

public static long GetTotalFragmentationInfo(NativeArray<int> stats);

参数

stats 一个用来接收的统计数据数组,它按大小的 2 的幂对自由块进行分组。如果给定一个小的数组,则 Unity 会将较大的自由块算在最终数组元素中。

返回

long 返回动态堆中的自由块的总数。

描述

返回堆内存碎片信息。

堆碎片是衡量动态堆中潜在无法使用空间大小的一种方式。如果应用程序的堆碎片太多,会导致内存分配失败。

对于一次分配来说,可能存在比应用程序需要的更多的可用内存,但由于这种可用内存由两个或更多更小的独立内存块组成,因此分配可能会失败。

在运行时,某些内存使用模式会导致自由块的数量随时间推移而增加,导致堆出现碎片。

例如,考虑 Unity 释放大分配时,一个单独的大自由块会被返回到堆中。如果之后没有可用的较小块,则这个较大的自由块可用于满足更多较小的分配。

如果除这个块中的单个分配之外的其他所有小分配被释放掉,那么堆现在有两个较小的自由块,它们位于单个剩余分配的两侧。如果之后没有较大的块可供使用,则重新分配最初的较大空间可能会失败。

由于 Unity 会动态分配和释放内存,它通过跟踪空闲内存块来管理堆区域。在内部,Unity 将这些空闲内存块按类似大小分组 - 分组为 2 的幂大小,介于 2 的一个幂和下一个幂之间,具体为 [(2^n) .. (2^(n+1) - 1)]。

例如,块大小为 [1]、[2..3]、[4..7]、[8..15]、[16..31]、[32..63]、[64..127]、[128..256] ... 字节。

此设计无论分配大小或堆容量如何,都能为所有分配提供快速且恒定的时间分配器性能。

您可以使用 Profiler.GetTotalFragmentationInfo 跟踪堆的空闲内存块过去一段时间的情况。

using Unity.Collections;
using UnityEngine;
using UnityEngine.Profiling;

public class Example : MonoBehaviour { const int kFreeBlockPow2Buckets = 24;

void Update() { var freeStats = new NativeArray<int>(kFreeBlockPow2Buckets, Allocator.Temp); var freeBlocks = Profiler.GetTotalFragmentationInfo(freeStats);

Debug.Log(string.Format("Total Free Blocks: {0}", freeBlocks)); for (int i = 0; i < kFreeBlockPow2Buckets; i++) { Debug.Log(string.Format(" size[2^{0}] = {1} blocks", i, freeStats[i])); } } }