當創建對象、 字符串或數組時,從中央池中稱為堆分配存儲它所需的內存。該項目時不再使用,它1次占用的內存可以回收,并用于別的東西。在過去,它通常是由http://www.jyygyx.com來分配和釋放這些塊堆內存使用適當的函數調用顯式。如今,像統1的單引擎的運行時系統會自動為您管理內存。自動內存管理需要少比顯式分配/釋放的編碼工作,極大地減少了潛伏的內存泄漏 (情況在哪里內存分配,但永久不會隨后釋放)。
值和援用類型
當1個函數被調用時,其參數的值復制到為這1具體要求保存的內存區域。可以復制占用只有幾個字節的數據類型,非常迅速和容易。但是,這是常見的對象、字符串和數組要大很多,如果這些類型的數據被復制在定期的基礎上,它將會非常低效。榮幸的是,這不是必要的 ;從堆分配1個大的項目的實際存儲空間和1個小的"指針"值,用來記住它的位置。從那時起,只有指針需要復制期間傳遞的參數。只要運行時系統可以找到由指針標識的項,可以作為必要時常常使用數據的單個副本。
直接存儲和復制期間參數傳遞的類型稱為值類型。這些包括整數、 浮點數、 布爾值和統1的結構類型(例如,色彩和Vector3)。在堆上分配,然后通過指針訪問的類型稱為援用類型,由于只是存儲在變量中的值"是指"真實的數據。援用類型的例子包括對象、 字符串和數組。
分配和垃圾回收
內存管理器跟蹤的領域它明知是未使用的堆中。當1座新的內存要求時 (說當1個對象被實例化)時,經理選擇要從中分配塊未使用的區域,然后從已知未使用的空間中刪除已分配的內存。后續要求的處理方式相同,直到沒有自由的范圍不夠大,沒法分配所需的塊大小。在這1點上是極不可能從堆中分配的所有內存都都仍在使用。只能訪問堆上的參考項目,只要仍有可以找到它的援用變量。如果指向的內存塊的所有援用都都不見了(即,援用變量已被重新分配或它們都是都現已超越范圍的本地變量) 然后它占用的內存可以安全地重新分配。
要肯定哪堆塊不再使用,內存管理器搜索所有當前活動的援用變量,并標志著他們稱為"活著"的塊。在搜索結束后,任何活塊之間的空間被認為是空的內存管理器,可以用于后續分配。緣由很明顯,定位和釋放未使用的內存的進程被稱為垃圾搜集(或簡稱 GC)。
優化
垃圾搜集是自動與不可見的http://www.jyygyx.com,但搜集進程實際上需要大量的 CPU時間,在幕后。如果應用得當,自動內存管理通常將等于或擊敗手動分配,以整體的性能。但是,相當重要的是對http://www.jyygyx.com來講,避免毛病,將觸發比必要更常常搜集器并介紹在履行暫停。
有1些臭名昭著的算法,可以是 GC的噩夢,雖然他們看起來無辜乍1看。重復字符串聯接是1個經典的例子:-
這里關鍵的細節是新片不會添加到地方中的字符串、 1個接1個。到底產生了甚么是周圍循環的每次行變量上之前的內容變得死寂了 ― ―1個全新的字符串分配包括原片加末尾的新部份。由于字符串獲得與增加值的我更長的時間,所用的堆空間正在消耗也增加,所以它是容易使用了數百個字節的可用堆空間的每次調用此函數。如果您需要將許多字符串聯接在1起更好的選擇是單聲道庫System.Text.StringBuilder類。
但是,即便重復的串連不會造成太多的麻煩,除非它叫做頻繁,并在通常意味著該框架的統1更新。就像:-
你什么時候分配新的字符串調用 Update時每次和生成新的垃圾不斷淌出。大多數是可以通過更新文本,僅當比分更改時保存:-
當1個函數返回數組值時產生的另外一個潛伏的問題:-
這類類型是函數的非常優雅,交通便捷,當創建1個新數組,用值填充。但是,如果它反復調用然后新鮮內存將分配每次。由于數組可以是很大,可用堆空間可以得到使用迅速上升,致使頻繁的垃圾回收。若要避免此問題的1種方法是要使用的數組是1個援用類型的事實。可以在這個函數中修改成1個函數作為參數傳遞的數組和結果不會在函數返回后。像上面常常被替換之類的功能:-
這只是用新值替換現有數組的內容。雖然這需要初始分配的數組必須在調用代碼中 (這看起來有點不雅),該函數將不會產生任何新的垃圾,當它被調用時。
要求集合
如上文所述,它最好盡可能避免分配。不過,既然他們不能完全消除,但也有兩個主要的策略,你可使用盡可能減少它們侵入游戲:-
這類策略常常是游戲的最好的有長時間在哪里光滑的幀速率是游戲的主要關注的游戲。這樣的比賽通常會頻繁地分配小塊,但這些塊將只扼要地被使用。在 iOS上使用這類策略時的典型堆大小是大約 200 KB,垃圾回收會約5ms的 iPhone 3g。如果堆增加到 1 MB時,該集合將約 7ms。因此,它可以有益于有時要求普通幀間隔的垃圾回收。這通常會使集合比嚴格必須更常常產生,但他們將處理速度快、 影響最小的游戲:-
但是,你應當謹慎使用這類技術,檢查事件探查器統計信息,以確保它真的減少搜集時間為你的游戲。
這1戰略合適的游戲撥款 (和集合) 是相對較少,可以在游戲暫停期間處理。它是用于堆是1樣大的而不是如此之大,讓您的利用程序由于系統內存不足 OS被殺害。但是,單聲道的運行時避免擴大堆自動如果可能的話。您可以通過在啟動進程中預1些占位符空間手動擴大堆 (即您實例化1個純潔的影響,內存管理器分配的"無用"對象):-
1個足夠大的堆應當不得到完全填滿那些暫停游戲,可以容納1個集合之間。這樣的停頓時,您可以顯式要求集合:-
再次,你應當照顧使用此策略時,注意到探查器統計信息而不只在假定它有預期的效果。
可重用的對象池
有很多情況下,在那里您可以免生成垃圾僅通過減少創建和燒毀的對象的數目。有某些類型的對象在游戲中,如子彈頭,可能會遇到幾遍,即便只有1小部份曾將播放1次。在這類情況下,很有可能要重用的對象,而不是摧毀舊的并替換為新的。
進1步的信息
內存管理是奧妙和復雜須大量的學術努力1直致力。如果你有興趣學習更多有關它memorymanagement.org是1種優秀的資源,列出了許多出版物和在線文章。在Sourcemaking.com上維基百科的頁面,可以找到有關對象池的進1步信息.