一、認識Unity的自動內存管理
unity應用佔用的內存可以分爲三類,託管堆、本機堆、引擎及代碼自身佔用的內存;本篇介紹的自動內存管理即託管堆的管理。
Unity爲我們做了一些自動的內存管理操作,但是我們也需要遵守一些規範才能讓這種機制更好的發揮作用,所以我們需要了解一下unity自動內存管理究竟做了什麼;
我們知道當一個Object,字符串或數組被創建時,計算機會在堆中爲其分配內存;但它不在使用的時候,內存就會被回收;在之前都是由開發者分配和釋放堆內存,但是運行時runtime system如Unity的Mono,C#的CLR會提供自動的內存管理;
1.值類型和引用類型
值類型:一般佔用較少的字節數,傳遞時直接複製成本較低;
引用類型:如字符串、數組等,直接複製效率非常低,所以在堆中存儲,然後通過指針訪問,指針自身是存儲在棧中的;
2.分配和垃圾收集
內存管理器跟蹤它知道的未使用的堆中的區域,當實例化一個對象需要請求內存時,管理器選擇一個未使用的內存區域來分配該塊,然後從已知的未使用的空間中刪除已分配的內存;但是如果已知的可使用的內存不夠用了,而實際情況確是,從對分配的所有內存都在使用的可能性很小,我們需要找出那些已經沒有被引用的內存塊,然後重新分配其佔用的內存(注意內存泄漏),這種查找釋放的過程就是GC;
每當Unity需要進行GC操作時,它都會停止運行程序代碼,並且在GC完成之後工作才能恢復正常運行,這種中斷很可能造成遊戲延遲,從1ms到上百ms不等,也就是意味着當GC進行時,我們無法維持平滑動畫所需要的幀率,這些中斷也稱爲GC峯值,我們可以在Profiler中去觀察到;
3.什麼是內存分配
首先要了解計算機的存儲結構,瞭解計算機內存的基本概念;
二、進階
1.unity中具體的內存分配策略
參考:WeTest-內存是手遊的硬傷——Unity遊戲Mono內存管理及泄漏
Mono通過垃圾回收機制(Garbage Collect,簡稱GC)對內存進行管理。Mono內存分爲兩部分,已用內存(used)和堆內存(heap),已用內存指的是mono實際需要使用的內存,堆內存指的是mono向操作系統申請的內存,兩者的差值就是mono的空閒內存。當mono需要分配內存時,會先查看空閒內存是否足夠,如果足夠的話,直接在空閒內存中分配,否則mono會進行一次GC以釋放更多的空閒內存,如果GC之後仍然沒有足夠的空閒內存,則mono會向操作系統申請內存,並擴充堆內存,具體如下圖所示。
2.內存泄漏
Unity下的內存泄漏,主要分爲代碼側的泄漏和資源側的泄漏,當然,資源側的泄漏也是因爲在代碼中對資源的不合理引用引起的。具體可參考:Unity內存優化之內存泄漏、內存冗餘;