为什么这个内存管理技巧有效

本文关键字:有效 管理 内存 为什么 | 更新日期: 2023-09-27 17:49:38

参考Unity文档并进入

章节

大堆,缓慢但不频繁的垃圾收集

    var tmp = new System.Object[1024];
    // make allocations in smaller blocks to avoid them to be treated in a special way, which is designed for large blocks
    for (int i = 0; i < 1024; i++)
        tmp[i] = new byte[1024];
    // release reference
    tmp = null;

诀窍是在程序开始时预先分配一些内存块。

为什么这个技巧有效?

这些块在预分配时是否被"注册"(或"绑定")到应用程序,因此即使tmpStart()完成时被释放,操作系统仍然将这些块视为"注册"到应用程序?由于块是"注册"到应用程序的,所以应用程序的堆大小被扩展到一定的大小,下一次它获得内存块时,操作系统只会从这个应用程序的堆中选择它。

我的解释正确吗?无论是或否,谁能解释得更详细一些,谢谢。

为什么这个内存管理技巧有效

这不是一个真正的技巧。这是Unity3D处理内存的方式。

在Unity3D中,你有由Mono处理并将被垃圾收集的对象,以及由Unity处理的对象,这将不会被垃圾收集。字符串,整型等由Mono自动清理,我们不必担心这一点。纹理(2D)等不是,我们必须手动处理这些对象。

当发出内存请求时,发生的第一件事是内存管理器从操作系统扫描应用程序当前分配的内存,以寻找足够大的块来存储您正在请求的数据。如果找到匹配项,则使用该内存。如果没有找到匹配项,那么应用程序将从操作系统请求额外的内存来存储数据。当这些数据不再用完时,它将被垃圾收集,但应用程序仍然保留这些内存。本质上,它在内存上设置一个标志,表示它是"可用的"或可重新分配的。这减少了对操作系统的内存请求,因为它永远不会返回内存。

这意味着两件事;

1)应用程序的内存只会继续增长,不会将内存返回给操作系统。在移动设备上,这是危险的,因为如果您使用太多内存,您的应用程序将被终止。

2)您的应用程序实际上可能被分配了比实际需要更多的内存。这是由于内存碎片。应用程序的内存池中可能有10MB的可用内存,但这些内存块都不足以容纳需要存储的数据。因此,应用程序可能会向操作系统请求更多的内存,因为没有一块连续的可用内存可以使用。

因为您正在创建一个大对象,因此请求内存,当您将该对象设置为null并向垃圾收集器发出信号表明应用程序不再需要内存时,将保留的内存重新分配给其他对象比从操作系统请求额外内存更快。这就是为什么从理论上讲,这种特定的方法速度很快,并且由于调用垃圾收集器的频率较低,导致性能峰值较小的原因。特别是这是一个大的、连续的内存分配。

为什么这个技巧有效?

这个技巧是有效的,因为应用程序不会将内存返回给操作系统,除非操作系统内存管理器很低,并且显式地请求它们这样做,在这种情况下,它们将尽可能多地释放内存。有一个假设是,一旦分配了内存,就会再次需要它。如果它已经被分配了,就没有理由将它返回给操作系统,除非它确实需要使用它。