jvm總結(jié)篇

內(nèi)存模型以及分區(qū),需要詳細到每個區(qū)放什么。

JVM 分為堆區(qū)和棧區(qū),還有方法區(qū),初始化的對象放在堆里面,引用放在棧里面,class類信息常量池(static常量和static變量)等放在方法區(qū)

  • 方法區(qū):主要是存儲類信息,常量池(static常量和static變量),編譯后的代碼(字節(jié)碼)等數(shù)據(jù)
  • 堆:初始化的對象,成員變量 (那種非static的變量),所有的對象實例和數(shù)組都要在堆上分配
  • 棧:棧的結(jié)構(gòu)是棧幀組成的,調(diào)用一個方法就壓入一幀,幀上面存儲局部變量表,操作數(shù)棧,方法出口等信息,局部變量表存放的是8大基礎類型加上一個應用類型,所以還是一個指向地址的指針
  • 本地方法棧:主要為Native方法服務
  • 程序計數(shù)器:記錄當前線程執(zhí)行的行號

堆里面的分區(qū):Eden,survival (from+ to),老年代,各自的特點。

堆里面分為新生代和老生代(java8取消了永久代,采用了Metaspace),新生代包含Eden+Survivor區(qū),survivor區(qū)里面分為from和to區(qū),內(nèi)存回收時,如果用的是復制算法,從from復制到to,當經(jīng)過一次或者多次GC之后,存活下來的對象會被移動到老年區(qū),當JVM內(nèi)存不夠用的時候,會觸發(fā)Full GC,清理JVM老年區(qū)
當新生區(qū)滿了之后會觸發(fā)YGC,先把存活的對象放到其中一個Survice區(qū),然后進行垃圾清理。因為如果僅僅清理需要刪除的對象,這樣會導致內(nèi)存碎片,因此一般會把Eden 進行完全的清理,然后整理內(nèi)存。那么下次GC 的時候,就會使用下一個Survive,這樣循環(huán)使用。如果有特別大的對象,新生代放不下,就會使用老年代的擔保,直接放到老年代里面。因為JVM 認為,一般大對象的存活時間一般比較久遠。

對象存活判斷

引用計數(shù):每個對象有一個引用計數(shù)屬性,新增一個引用時計數(shù)加1,引用釋放時計數(shù)減1,計數(shù)為0時可以回收。此方法簡單,無法解決對象相互循環(huán)引用的問題。
可達性分析(Reachability Analysis):從GC Roots開始向下搜索,搜索所走過的路徑稱為引用鏈。當一個對象到GC Roots沒有任何引用鏈相連時,則證明此對象是不可用的。不可達對象。

在Java語言中,GC Roots包括:
虛擬機棧中引用的對象。
方法區(qū)中類靜態(tài)屬性實體引用的對象。
方法區(qū)中常量引用的對象。
本地方法棧中JNI引用的對象。

SafePoint是什么

比如GC的時候必須要等到Java線程都進入到safepoint的時候VMThread才能開始執(zhí)行GC,

  1. 循環(huán)的末尾 (防止大循環(huán)的時候一直不進入safepoint,而其他線程在等待它進入safepoint)
  2. 方法返回前
  3. 調(diào)用方法的call之后
  4. 拋出異常的位置

GC的三種收集方法:標記清除、標記整理、復制算法的原理與特點,分別用在什么地方,如果讓你優(yōu)化收集方法,有什么思路?

標記:標記完畢之后再清除,效率不高,會產(chǎn)生碎片
復制算法:分為8:1的Eden區(qū)和survivor區(qū),就是上面談到的YGC
標記整理:標記完畢之后,讓所有存活的對象向一端移動

GC收集器有哪些?CMS收集器與G1收集器的特點。

串行收集器:串行收集器使用一個單獨的線程進行收集,GC時服務有停頓時間
并行收集器:次要回收中使用多線程來執(zhí)行
CMS:基于“標記—清除”算法實現(xiàn)的,經(jīng)過多次標記才會被清除
G1:從整體來看是基于“標記—整理”算法實現(xiàn)的收集器,從局部(兩個Region之間)上來看是基于“復制”算法實現(xiàn)的

Minor GC與Full GC分別在什么時候發(fā)生?

新生代內(nèi)存不夠用時候發(fā)生MGC也叫YGC,JVM內(nèi)存不夠的時候發(fā)生FGC

幾種常用的內(nèi)存調(diào)試工具:jmap、jstack、jconsole、jhat

stack可以看當前棧的情況,jmap查看內(nèi)存,jhat 進行dump堆的信息
mat(eclipse的也要了解一下)

g1 和 cms 區(qū)別,吞吐量優(yōu)先和響應優(yōu)先的垃圾收集器選擇

CMS是一種以最短停頓時間為目標的收集器,響應優(yōu)先選擇CMS,吞吐量高選擇G1

類加載的幾個過程

加載、驗證、準備、解析、初始化。然后是使用和卸載了
通過全限定名來加載生成class對象到內(nèi)存中,然后進行驗證這個class文件,包括文件格式校驗、元數(shù)據(jù)驗證,字節(jié)碼校驗等。準備是對這個對象分配內(nèi)存。解析是將符號引用轉(zhuǎn)化為直接引用(指針引用),初始化就是開始執(zhí)行構(gòu)造器的代碼

雙親委派模型

Bootstrap ClassLoader:啟動類加載器,負責將 Java_Home/lib下面的類庫加載到內(nèi)存中。(比如rt.jar)
Extension ClassLoader:標準擴展(Extension)類加載器,它負責將$Java_Home /lib/ext或者由系統(tǒng)變量 java.ext.dir指定位置中的類庫加載到內(nèi)存中。
ApplicationClassLoader:它負責將系統(tǒng)類路徑(CLASSPATH)中指定的類庫加載到內(nèi)存中。開發(fā)者可以直接使用系統(tǒng)類加載器
雙親委派模型是某個特定的類加載器在接到加載類的請求時,首先將加載任務委托給父類加載器,依次遞歸,如果父類加載器可以完成類加載任務,就成功返回;只有父類加載器無法完成此加載任務時,才自己去加載。-----例如類java.lang.Object,它存在在rt.jar中,無論哪一個類加載器要加載這個類,最終都是委派給處于模型最頂端的Bootstrap ClassLoader進行加載,因此Object類在程序的各種類加載器環(huán)境中都是同一個類。相反,如果沒有雙親委派模型而是由各個類加載器自行加載的話,如果用戶編寫了一個java.lang.Object的同名類并放在ClassPath中,那系統(tǒng)中將會出現(xiàn)多個不同的Object類,程序?qū)⒒靵y

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

少喝酒,少抽煙,少熬夜。多跑步,多喝茶,多看書。健康是最大的本錢,平安是福,對人對己,都是。學著感恩,學著理解,學著友善。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

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

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

  • 前言: 在遨游了一番 Java Web 的世界之后,發(fā)現(xiàn)了自己的一些缺失,所以就著一篇深度好文:知名互聯(lián)網(wǎng)公司校招...
    我沒有三顆心臟閱讀 10,638評論 15 121
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡上收集的一些資料的整理,因此不免有一些不準確的地方,同時不同JDK版本的...
    高廣超閱讀 16,040評論 3 83
  • 介紹JVM中7個區(qū)域,然后把每個區(qū)域可能造成內(nèi)存的溢出的情況說明 程序計數(shù)器:看做當前線程所執(zhí)行的字節(jié)碼行號指示器...
    jemmm閱讀 2,303評論 0 9
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,753評論 11 349
  • 大家晚上好,歡迎來到懂球帝中超三月最佳主教練的頒獎現(xiàn)場。綜合三方投票,在新賽季率領(lǐng)魯能獲得兩連勝的馬加特當選懂球帝...
    小小飛毛腿閱讀 252評論 0 0

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