Anroid內(nèi)存筆記 -- 內(nèi)存及GC概念

Java內(nèi)存區(qū)域

Java虛擬機(jī)在執(zhí)行Java程序時, 會把管理的內(nèi)存, 分為幾個區(qū)域;
平時我們一般粗略的分成棧和堆; 棧存放對象引用指針, 堆則存放棧中指針指向的對象;

Java虛擬機(jī)棧

  1. 線程私有, 生命周期和Thread相同;
  2. 虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型: 每個方法執(zhí)行時,都會創(chuàng)建一個棧幀, 用于存儲局部變量表,操作數(shù)棧,動態(tài)鏈接,方法出口等信息;每一個方法執(zhí)行,都對應(yīng)一個棧幀在虛擬機(jī)棧中入棧到出棧;
  3. 平時我們說的棧,即局部變量表; 它存放了編譯器可知的各種基本數(shù)據(jù)類型, 和對象引用等

Java堆

  1. Java堆是被所有線程共享內(nèi)存區(qū)域, 在虛擬機(jī)啟動時創(chuàng)建;
  2. 用來存放對象實例, 幾乎所有的對象實例和數(shù)組都在此分配內(nèi)存;
  3. Java堆是內(nèi)存回收的主要區(qū)域,很多時候稱之為GC堆

方法區(qū)

  1. 各個線程共享的內(nèi)存區(qū)域
  2. 用來存放被虛擬機(jī)加載的類信息,常量,靜態(tài)變量,編譯器編譯后的代碼等
  3. 也稱之為Non-Heap(非堆), 自己程序開發(fā)一般不關(guān)注 - -

垃圾收集器

gc收集時, 需要完成3件事:

  1. 哪些內(nèi)存需要回收
  2. 什么時候回收
  3. 如何回收

判斷那些內(nèi)存需要回收

回收時,肯定要確定哪些對象要被回收,要判斷哪些對象已死(即不可達(dá));

引用計數(shù)法

給對象一個引用計數(shù)器, 每當(dāng)一個地方引用它時, 計數(shù)器加1; 當(dāng)引用失效時, 計數(shù)器減1; 任何時候計數(shù)器為0的對象, 即不可達(dá)對象, 可被回收;
引用技術(shù)簡單, 但遇見相互引用時, 無法判定; eg, A引用B, B同時引用A, A和B都不再有其他任何引用, 實際對象不可訪問, 但是引用計數(shù)器卻不為0;

可達(dá)性分析

通過一系列GC Root對象作為起點, 從這些節(jié)點向下搜索,搜索走過的路徑稱之為引用鏈, 當(dāng)一個對象到GC Root沒有任何引用鏈來連接時, 則此對象不可達(dá), 可以用來回收;
而用來作為GC Root的對象有下面幾種:

  1. 虛擬機(jī)棧,即本地變量表中引用的對象
  2. 方法區(qū)中靜態(tài)屬性引用的對象
  3. 方法區(qū)中常量引用的對象
  4. 本地方法棧JNI, 即Native方法引用的對象

垃圾收集算法

標(biāo)記-清除算法

Mark-Sweep算法,如同名稱一樣, 分標(biāo)記和清楚兩步: 首先標(biāo)記出需要回收的對象, 在標(biāo)記完成后, 統(tǒng)一回收所有被標(biāo)記的對象;
主要有2個不足: 一是效率, 標(biāo)記和清除效率都不高; 二是空間問題, 清除后會產(chǎn)生大量的不連續(xù)的內(nèi)存碎片, 空間碎片太多,可能導(dǎo)致程序運行時, 需要分配較大內(nèi)存的對象時, 無法找到足夠的連續(xù)內(nèi)存而不得不在一次觸發(fā)gc;

復(fù)制算法

為了解決效率問題, Copying的收集算法出現(xiàn)了, 將內(nèi)存分為容量相等的兩塊, 每次只使用其中一塊, 當(dāng)一塊內(nèi)存用完時, 就將還存活著的對象復(fù)制到另一塊上去, 然后把已使用過的內(nèi)存一次清理;

標(biāo)記-整理算法

先需要從根節(jié)點開始對所有可達(dá)對象做一次標(biāo)記,但之后,它并不簡單地清理未標(biāo)記的對象,而是將所有的存活對象壓縮到內(nèi)存的一端。之后,清理邊界外所有的空間。這種方法既避免了碎片的產(chǎn)生,又不需要兩塊相同的內(nèi)存空間;

分代收集算法

將所有的新建對象都放入稱為年輕代的內(nèi)存區(qū)域,年輕代的特點是對象會很快回收,因此,在年輕代就選擇效率較高的復(fù)制算法。當(dāng)一個對象經(jīng)過幾次回收后依然存活,對象就會被放入稱為老生代的內(nèi)存空間。對于新生代適用于復(fù)制算法,而對于老年代則采取標(biāo)記-整理,或者標(biāo)記-清除算法

垃圾收集器

收集器是真正實現(xiàn)收集算法的地方,有各種版本, 主要說下CMS

CMS收集器

Concurrent Mark Sweep, 名稱可以看出是基友標(biāo)記-清除算法的收集器; 為了使用回收停頓時間(Stop The World`)最短為目標(biāo)的收集器;
工作流程分為下面幾個步驟:

  1. 初始標(biāo)記, CMS initial mark
  2. 并發(fā)標(biāo)記, CMS concurrent mark
  3. 重新標(biāo)記, CMS remark
  4. 并發(fā)清楚, CMS concurrent sweep

其中,初始標(biāo)記和重新標(biāo)記需要Stop The World. 初始標(biāo)記僅標(biāo)記GC Root能直接關(guān)聯(lián)的對象; 并發(fā)標(biāo)記即進(jìn)行初始標(biāo)記后的引用可達(dá)遍歷; 重新標(biāo)記則是修正并發(fā)標(biāo)記期間程序繼續(xù)運行而導(dǎo)致標(biāo)記變動的對象;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 原文閱讀 前言 這段時間懈怠了,罪過! 最近看到有同事也開始用上了微信公眾號寫博客了,挺好的~給他們點贊,這博客我...
    碼農(nóng)戲碼閱讀 6,150評論 2 31
  • 1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虛擬機(jī)(JVM)垃圾回收器提供...
    簡欲明心閱讀 90,372評論 17 311
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡(luò)上收集的一些資料的整理,因此不免有一些不準(zhǔn)確的地方,同時不同JDK版本的...
    高廣超閱讀 16,051評論 3 83
  • 《深入理解Java虛擬機(jī)》筆記_第一遍 先取看完這本書(JVM)后必須掌握的部分。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,473評論 1 34
  • JVM架構(gòu) 當(dāng)一個程序啟動之前,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū)),執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,836評論 0 7

友情鏈接更多精彩內(nèi)容