記憶體洩漏的廣義定義:在電腦科學中,由於疏忽或錯誤造成程式未能釋放已經不再使用的記憶體,記憶體洩漏並非指內存在物理上的消失,而是應用程式分配某段記憶體後,由於設計錯誤,導致在釋放該段記憶體之前就失去了對該段記憶體的控制,從而造成了記憶體的浪費。
後果:記憶體洩漏會因為減少可用記憶體的數量從而降低計算機的效能,比如引發頻繁的gc,引發頻繁記憶體申請等,在最糟糕的情況下,可能會導致應用程式崩潰。
主要參考:uwa:效能優化,進無止境---記憶體篇(下)
主要是兩種託管堆記憶體洩漏和資源記憶體洩漏
判斷記憶體洩漏最簡單的方式,用進入乙個場景之前的記憶體和這個場景退出後的記憶體占用資料做對比,如果記憶體占用出現了不合理的增加,則可能出現了記憶體洩漏。
注意,這裡有乙個誤區,即進出場景檢查記憶體占用時,只要有記憶體占用的增加就是記憶體洩漏。
託管堆記憶體的洩漏主要是由一些不規範的**導致的,這一部分可參考unity官方文件:unity manual:了解託管堆
資源記憶體洩漏就是native記憶體洩漏,與程式託管堆記憶體洩漏不同,資源記憶體洩漏都是因為載入資源後沒有釋放造成的,也有在邏輯中拷貝乙份資源但是沒有解除安裝導致的。
檢查資源的使用情況,特別是紋理、網格等資源的使用
資源洩漏是記憶體洩漏的主要方式,而且資源洩漏導致的記憶體洩漏顯然是更嚴重的,乙個常見的原因是開發者對載入後的資源進行了儲存,比如放到了乙個容器中,那麼如果在場景切換時沒有remove或clear,那麼無論從引擎本身還是手動呼叫resources.unloadunusedassets等相關api均無法對其進行解除安裝,從而造成了資源洩漏。
uwa推出的場景比較功能,即比較場景的兩個記憶體快照,來判斷哪些資源(非常駐資源)可能導致了記憶體洩漏。
unity所使用的mono版本中有乙個問題:記憶體一旦分配,則不會返還給作業系統。所以,即使沒有發生記憶體洩漏,也不能保證記憶體的使用沒有問題,而無效的堆記憶體的問題也應該引起重視,無效對記憶體是指:mono分配了堆記憶體,但是沒有被真正利用,因此無效。
在memory profiler中,reserved total是當前專案所佔據的總物理記憶體(也就是分配的記憶體),而used total為當前專案所使用的總物理記憶體,這兩者的差值就是無效記憶體,無效記憶體由兩部分組成,空閒的unity引擎記憶體和無效的mono堆記憶體,我們可以根據profiler資訊分別得出兩部分記憶體大小。
如何避免
記憶體管理中,有乙個重要的問題就是資源冗餘,所謂資源冗餘,是指同一時刻記憶體中存在兩份甚至多份同樣的資源。
資源的例項化導致
當修改了一些特定的gameobject屬性時,引擎會為該gameobject自動例項化乙份資源供其使用,比如material、mesh等。
最常見的就是material,如果修改了material,就會立即看到inpector的material後多了instance字尾,如果有大量的更改需求,就會增加記憶體冗餘。
QT之記憶體洩漏
以入門的hello world 為例 我們將 main.cpp 修改如下 include include intmain int argc,char ar 示例程式我們已經講解完畢。下面再說一點。我們可以將上面的程式改寫成下面的 嗎?include include intmain int argc,...
Unity效能優化之記憶體篇
效能優化,進無止境 記憶體篇 上 效能優化,進無止境 記憶體篇 下 本篇主旨是總結兩篇內容的重點,細節還請在作者文章檢視。1.資源記憶體占用 2.引擎模組自身記憶體占用 3.託管堆記憶體占用。4.記憶體洩露。5.無效的mono堆記憶體開銷。6.資源冗餘。資源的記憶體占用往往佔據了總體記憶體的70 以...
C 之記憶體洩漏篇
前段時間面試經常被問到記憶體洩漏。今天小總結一下 記憶體洩漏的發生是由於使用者在堆上分配了空間,但卻沒有釋放它。持續的記憶體洩漏最終將導致堆的耗盡,後繼的記憶體分配將會失敗。引發記憶體洩漏的原因是用new分配的記憶體沒有用delete釋放掉。如 可能在onpaint這樣的繪畫視窗的函式中分配了空間,...