程序员人生 网站导航

了解自动内存管理

栏目:互联网时间:2014-11-25 08:12:12


了解自动内存管理


当创建对象、 字符串或数组时,从中央池中称为分配存储它所需的内存。该项目时不再使用,它1次占用的内存可以回收,并用于别的东西。在过去,它通常是由http://www.wfuyu.com来分配和释放这些块堆内存使用适当的函数调用显式。如今,像统1的单引擎的运行时系统会自动为您管理内存。自动内存管理需要少比显式分配/释放的编码工作,极大地减少了潜伏的内存泄漏 (情况在哪里内存分配,但永久不会随后释放)。

值和援用类型

当1个函数被调用时,其参数的值复制到为这1具体要求保存的内存区域。可以复制占用只有几个字节的数据类型,非常迅速和容易。但是,这是常见的对象、字符串和数组要大很多,如果这些类型的数据被复制在定期的基础上,它将会非常低效。荣幸的是,这不是必要的 ;从堆分配1个大的项目的实际存储空间和1个小的"指针"值,用来记住它的位置。从那时起,只有指针需要复制期间传递的参数。只要运行时系统可以找到由指针标识的项,可以作为必要时常常使用数据的单个副本。

直接存储和复制期间参数传递的类型称为值类型。这些包括整数、 浮点数、 布尔值和统1的结构类型(例如,色彩和Vector3)。在堆上分配,然后通过指针访问的类型称为援用类型,由于只是存储在变量中的值"是指"真实的数据。援用类型的例子包括对象、 字符串和数组。

分配和垃圾回收

内存管理器跟踪的领域它明知是未使用的堆中。当1座新的内存要求时 (说当1个对象被实例化)时,经理选择要从中分配块未使用的区域,然后从已知未使用的空间中删除已分配的内存。后续要求的处理方式相同,直到没有自由的范围不够大,没法分配所需的块大小。在这1点上是极不可能从堆中分配的所有内存都都仍在使用。只能访问堆上的参考项目,只要仍有可以找到它的援用变量。如果指向的内存块的所有援用都都不见了(即,援用变量已被重新分配或它们都是都现已超越范围的本地变量) 然后它占用的内存可以安全地重新分配。

要肯定哪堆块不再使用,内存管理器搜索所有当前活动的援用变量,并标志着他们称为"活着"的块。在搜索结束后,任何活块之间的空间被认为是空的内存管理器,可以用于后续分配。缘由很明显,定位和释放未使用的内存的进程被称为垃圾搜集(或简称 GC)。

优化

垃圾搜集是自动与不可见的http://www.wfuyu.com,但搜集进程实际上需要大量的 CPU时间,在幕后。如果应用得当,自动内存管理通常将等于或击败手动分配,以整体的性能。但是,相当重要的是对http://www.wfuyu.com来讲,避免毛病,将触发比必要更常常搜集器并介绍在履行暂停。

有1些臭名昭著的算法,可以是 GC的噩梦,虽然他们看起来无辜乍1看。重复字符串联接是1个经典的例子:-

function ConcatExample(intArray: int[]) {
    var line = intArray[0].ToString();
   
    for (i = 1; i < intArray.Length; i++) {
        line += ", " + intArray[i].ToString();
    }
   
    return line;
}
 
 

这里关键的细节是新片不会添加到地方中的字符串、 1个接1个。到底产生了甚么是周围循环的每次行变量上之前的内容变得死寂了 ― ―1个全新的字符串分配包括原片加末尾的新部份。由于字符串获得与增加值的我更长的时间,所用的堆空间正在消耗也增加,所以它是容易使用了数百个字节的可用堆空间的每次调用此函数。如果您需要将许多字符串联接在1起更好的选择是单声道库System.Text.StringBuilder类。

但是,即便重复的串连不会造成太多的麻烦,除非它叫做频繁,并在通常意味着该框架的统1更新。就像:-

var scoreBoard: GUIText;
var score: int;
 
function Update() {
    var scoreText: String = "Score: " + score.ToString();
    scoreBoard.text = scoreText;
}
 
 

你什么时候分配新的字符串调用 Update时每次和生成新的垃圾不断淌出。大多数是可以通过更新文本,仅当比分更改时保存:-

var scoreBoard: GUIText;
var scoreText: String;
var score: int;
var oldScore: int;
 
function Update() {
    if (score != oldScore) {
        scoreText = "Score: " + score.ToString();
        scoreBoard.text = scoreText;
        oldScore = score;
    }
}
 
 

当1个函数返回数组值时产生的另外一个潜伏的问题:-

function RandomList(numElements: int) {
    var result = new float[numElements];
   
    for (i = 0; i < numElements; i++) {
        result[i] = Random.value;
    }
   
    return result;
}
 
 

这类类型是函数的非常优雅,交通便捷,当创建1个新数组,用值填充。但是,如果它反复调用然后新鲜内存将分配每次。由于数组可以是很大,可用堆空间可以得到使用迅速上升,致使频繁的垃圾回收。若要避免此问题的1种方法是要使用的数组是1个援用类型的事实。可以在这个函数中修改成1个函数作为参数传递的数组和结果不会在函数返回后。像上面常常被替换之类的功能:-

function RandomList(arrayToFill: float[]) {
    for (i = 0; i < arrayToFill.Length; i++) {
        arrayToFill[i] = Random.value;
    }
}
 
 

这只是用新值替换现有数组的内容。虽然这需要初始分配的数组必须在调用代码中 (这看起来有点不雅),该函数将不会产生任何新的垃圾,当它被调用时。

要求集合

如上文所述,它最好尽可能避免分配。不过,既然他们不能完全消除,但也有两个主要的策略,你可使用尽可能减少它们侵入游戏:-

具有快速和频繁的垃圾回收的小堆

这类策略常常是游戏的最好的有长时间在哪里光滑的帧速率是游戏的主要关注的游戏。这样的比赛通常会频繁地分配小块,但这些块将只扼要地被使用。在 iOS上使用这类策略时的典型堆大小是大约 200 KB,垃圾回收会约5ms iPhone 3g。如果堆增加到 1 MB时,该集合将约 7ms。因此,它可以有益于有时要求普通帧间隔的垃圾回收。这通常会使集合比严格必须更常常产生,但他们将处理速度快、 影响最小的游戏:-

if (Time.frameCount % 30 == 0)
{
   System.GC.Collect]();
}
 
 

但是,你应当谨慎使用这类技术,检查事件探查器统计信息,以确保它真的减少搜集时间为你的游戏。

大堆与缓慢但很少产生垃圾回收

这1战略合适的游戏拨款 (和集合) 是相对较少,可以在游戏暂停期间处理。它是用于堆是1样大的而不是如此之大,让您的利用程序由于系统内存不足 OS被杀害。但是,单声道的运行时避免扩大堆自动如果可能的话。您可以通过在启动进程中预1些占位符空间手动扩大堆 (即您实例化1个纯洁的影响,内存管理器分配的"无用"对象):-

function Start() {
    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 (var i : int = 0; i < 1024; i++)
        tmp[i] = new byte[1024];
 
    // release reference
        tmp = null;
}
 
 
 

1个足够大的堆应当不得到完全填满那些暂停游戏,可以容纳1个集合之间。这样的停顿时,您可以显式要求集合:-

System.GC.Collect();
 
 

再次,你应当照顾使用此策略时,注意到探查器统计信息而不只在假定它有预期的效果。

可重用的对象池

有很多情况下,在那里您可以免生成垃圾仅通过减少创建和烧毁的对象的数目。有某些类型的对象在游戏中,如子弹头,可能会遇到几遍,即便只有1小部份曾将播放1次。在这类情况下,很有可能要重用的对象,而不是摧毁旧的并替换为新的。

进1步的信息

内存管理是奥妙和复杂须大量的学术努力1直致力。如果你有兴趣学习更多有关它memorymanagement.org是1种优秀的资源,列出了许多出版物和在线文章。在Sourcemaking.com维基百科的页面,可以找到有关对象池的进1步信息.

 

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐