如何在虛擬世界活的更久一點之一什麼是內存泄露(Memory Leak)? 前言 內存泄露的定義 內存泄露的一些場景 關於對這個世界的認識的思考

前言

     沒有完美的人,也沒有完美的系統。
     在這個虛擬級別越來越高的世界中,你需要了解一個名詞“內存泄露”
     如果你不瞭解計算機,不瞭解程序,只是一個“普通人”,但是你希望更好的瞭解這個世界,那麼去認知“內存泄露”可以給你一個不同的角度去理解我們生活的真實世界。
     如果你是一名程序員,你與“內存泄露”有更多次相遇的機會,在C、C++、Java、Python等各種計算機語言構建的系統中,你總能遇到它,你需要重視它,解決它,但首先你需要辨明它。
     如何去辨明內存泄露呢?在探究多個系統後,這裏大膽給出一個廣義的定義。有了這個定義 ,我們便有了一雙識別“妖魔”的眼睛,然後我們聚焦在Android運行環境中,去辨明常見的一些內存泄露。

內存泄露的定義

廣義定義

     在計算機運行過程中,如果有對象超出了預期的生命週期繼續存活在內存中,導致這部分內存不能正常地回收和重新利用,我們就說發生了內存泄露。
     定義中有幾個點需要說明下:
     1)內存泄露是在系統運行過程中發生的。
     2)定義中的對象可指萬物,在計算機虛擬世界中,萬物需要進入內存中才能活過來。
     3)每個對象在被創造出來的時候都會被賦予一定的使命,爲了完成使命而存在的時空範圍就是它的生命週期,所謂超出預期生命週期就是這個對象在完成自己使命後沒有按既定的規律死掉,比如延遲死亡或者成爲不死怪物。

Android系統中內存泄露的定義

    在Android系統中,內存泄露主要指虛擬機在進行垃圾回收(GC)時候, 應該被回收的對象卻沒有被回收。
    垃圾回收(GC)其實就是讓超過預期生命週期的對象死掉,讓他們佔有的內存可以重新利用,這是一種系統行爲。在對象看來,這是它所處環境下的一種定律。
    這裏有兩個問題:
     1) 什麼時候進行垃圾回收(GC)呢?
答:垃圾回收的目的是爲了使內存能夠(更好的)重新利用。所以當需要創建新對象但發現內存不足時,系統會觸發GC;當碎片化嚴重等造成重新利用內存效率低時候,系統會觸發GC;當用戶主動調用時,系統會觸發GC。
    2 )在垃圾回收(GC)時候系統如何判斷一個對象是否已經達到自己生命週期,應該死掉?
答:爲了完成某個的使命,一個對象活了過來,它與很多其他對象,創造它的對象、傳達使命的對象、協助它的對象、管理資源的對象、彙報使命的對象等建立了聯接,它克服了很多困難,最終完成了自己的使命。一旦完成了使命,所有的這些聯接都要斷掉,然後這個對象就等待着最後終結-銷燬。
     最開始的系統判斷一個對象是否應該走向終結就是利用引用計數法,如果一個對象被另一個對象引用或者叫依賴、必需要,那麼引用計數就+1,當引用失效時候,計數器就-1,當這個數字爲零,這個對象不再被任何對象引用(需要),這個對象就處於待死狀態,等待GC回收。但這種方法很容易出現一個問題,那就是如果兩個對象相互引用,那麼就算它們都完成了自己的使命也不會被回收。
    鑑於上述情況,現在大多數系統演化出另外一種方法-可達性分析法。在這種方法下,判斷一個對象是否銷燬就是看這個對象是否被一些重要對象直接或者間接依賴。這些重要對象或者是正在進行使命的對象、或者是生命與整個系統(虛擬機對象)同在的對象、或者是被系統外部所引用的對象,在Android環境中有如下四種:
     1)虛擬機棧(局部變量表)中的引用的對象;
     2)仍處於存活狀態中的線程對象;
     3)方法區中靜態引用指向的對象;
     4)Native 方法中 JNI 引用的對象;
這四種對象被稱之爲GC ROOT(生命之根),在進行GC時候只要直接或者間接被GC ROOT引用,就不會處在系統的銷燬計劃中。所以從具體來看,在Android環境下內存泄露就是指當一個對象已經完成它的使命後,卻依舊處在某一種GC ROOT的引用鏈上。

內存泄露的一些場景

根據GC ROOT不同我們可以把常見的內存泄露分爲四大類:

這個還在持續補全中

關於對這個世界的認識的思考

    如果我們這個世界是虛擬的,芸芸衆生似我們不過是內存中一個個對象,那麼我們怎麼做才能避免被銷燬,更長久的存活下去呢?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章