【面試 JVM】【第六篇】JVM調優

六部份內容:html

一。內存模型前端

1.程序計數器,方法區,堆,棧,本地方法棧的做用,保存那些數據java

 能夠畫個大圖出來,很清晰面試

jvm內存模型主要指運行時的數據區,包括5個部分。算法

 

棧也叫方法棧,是線程私有的,線程在執行每一個方法時都會同時建立一個棧幀,用來存儲局部變量表、操做棧、動態連接、方法出口等信息。調用方法時執行入棧,方法返回時執行出棧。多線程

 

本地方法棧與棧相似,也是用來保存線程執行方法時的信息,不一樣的是,執行java方法使用棧,而執行native方法使用本地方法棧。框架

 

程序計數器保存着當前線程所執行的字節碼位置,每一個線程工做時都有一個獨立的計數器。程序計數器爲執行java方法服務,執行native方法時,程序計數器爲空。jvm

 

棧、本地方法棧、程序計數器這三個部分都是線程獨佔的。工具

 

堆是jvm管理的內存中最大的一塊,堆被全部線程共享,目的是爲了存放對象實例,幾乎全部的對象實例都在這裏分配。當堆內存沒有可用的空間時,會拋出OOM異常。根據對象存活的週期不一樣,jvm把堆內存進行分代管理,由垃圾回收器來進行對象的回收管理。性能

 

方法區也是各個線程共享的內存區域,又叫非堆區。用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據,

 

jdk1.7中的永久代和1.8中的metaspace都是方法區的一種實現。

 

面試回答此知識點相關問題時,要答出兩個要點:一個是各部分的功能,另外一個是哪些線程共享,哪些獨佔。

 

 

二。類加載機制

 1.雙親委派的加載機制

2.經常使用類加載器以及做用

3.雙親委派加載機制好處

4.如何判斷是同一個class

 

 

三。GC垃圾回收

 1.分代回收的思想和依據

 

java堆內存被分代管理,主要是爲了方便垃圾回收。

由於,第一,大部分對象很快就不使用了

第二,有一部分不會當即無用,但也不會持續很長的時間!

因此堆內存進行分代管理的劃分!

 

2.不一樣垃圾回收算法實現的思路以及適用的場景

 按類型分爲3種:

引用計數法:經過對象被引用的次數來肯定對象是否被使用,缺點沒法解決循環引用的問題!

 

複製算法:須要from和to兩塊大小相同的內存空間。對象分配只在from塊,回收時把存活對象複製到to塊,清空from,而後調換職權!from變成to,to變成from!缺點,內存使用率低!

 

標記清除算法:分爲標記對象和清除再也不使用的對象  兩個階段! 缺點,會產生內存碎片!

 

jvm中,年輕代回收算法serial、parNew、parallel scavenge都是複製算法!

CMS、G一、zgc都屬於標記清除算法!

 

 

四。性能調優

 1.經常使用jvm優化參數的做用

2.參數調優的依據

3.瞭解經常使用的jvm分析工具能分析哪類問題,以及使用方法

 

五。執行模式

 1.解釋,編譯,混合模式的優缺點

2.瞭解java7提供的分層編譯技術

3.知道JIT即時編譯技術和OSR棧上替換

4.知道C1,C2編譯器針對的場景,其中C2針對server模式,優化更激進

5.java10提供的由java實現的graal編譯器

 

 

六。編譯優化

 1.前端編譯器javac的編譯過程

2.AST抽象語法書

3.編譯期優化

4.運行期優化

5.編譯優化的經常使用技術

包括公共子表達式的消除,方法內聯,逃逸分析,棧上分配,同步消除等!明白了這些,才能寫出對編譯器友好的代碼!

 

 

 

 

 

 

 

 

 

1.JVM內存模型

 

  • Java堆:線程共享的,惟一目的就是用於存放對象實例,是垃圾收集器管理的主要區域;
  • Java虛擬機棧:線程私有的,每一個方法在執行的同時都會建立一個棧幀用於存儲局部變量等,局部變量表存放了編譯器可知的各類基本數據類型和對象引用
  • 本地方法棧:和虛擬機棧相似,不過它是爲Native方法服務;
  • 程序計數器:線程私有的,能夠看做是當前線程所執行的字節碼的行號指示器,以便線程切換後恢復執行使用;
  • 方法區:線程共享的,用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據;該區域的內存回收主要是針對常量池的回收和類型的卸載(特別是要注意一些動態字節碼框架和自定義ClassLoader的場景下);在HotSpot裏常常被稱爲永久代,在Java 8裏已被廢除了,被元空間取代

 

===============================================================

2.JVM內存回收機制

   1》堆內存

  堆內存是全部線程共有的,能夠分爲兩個部分:年輕代和老年代。下圖中的Perm表明的是永久代,可是注意永久代並不屬於堆內存中的一部分,同時jdk1.8以後永久代也將被移除。

  2》垃圾回收主要做用在堆內存

  3》新生代(Young Generation):用於存放新建立的對象,採用複製回收方法,若是在s0和s1之間複製必定次數後,轉移到年老代中。這裏的垃圾回收叫作minor GC;

  4》老年代(Old Generation):這些對象垃圾回收的頻率較低,採用的標記整理方法,這裏的垃圾回收叫作 major GC。

  

  拓展:1.在進行垃圾回收的時候,怎麼判斷哪些對象是垃圾,要被回收

  經過兩種方式

    1》引用計數【可是引用計數的方式沒法解決循環引用的問題】

    2》可達性分析

  拓展:2.什麼叫對象可達,什麼叫對象不可達,什麼是可達性分析

  經過一系列稱爲「GC Roots」的對象(好比虛擬機棧引用的對象、方法區中的類靜態屬性和常量引用對象)做爲起點,從這些節點一直往下搜索,走過的路徑稱爲引用鏈;而那些沒有與引用鏈相連的對象即爲不可達,會被回收。

  拓展:3.判斷對象能夠回收的狀況

    1》對象顯式的置空null

    2》局部引用指向的對象

    3》弱引用關聯的對象

===============================================================

3.什麼是GC,經常使用的GC算法有哪些?

  1》GC就是垃圾回收機制,就是JVM對內存中的對象進行管理的一個過程

  2》GC的過程以下:

1. Eden區最大,對外提供堆內存。當Eden區快要滿了,則進行Minor GC,把存活對象放入Survivor A區,清空Eden區;
2. Eden區被清空後,繼續對外提供堆內存;
3. 當Eden區再次被填滿,此時對Eden區和Survivor A區同時進行Minor GC,把存活對象放入Survivor B區,同時清空Eden 區和Survivor A區;
4. Eden區繼續對外提供堆內存,並重覆上述過程,即在Eden區填滿後,把Eden區和某個Survivor區的存活對象放到另外一個Survivor區;
5. 當某個Survivor區被填滿,且仍有對象未被複制完畢時或者某些對象在反覆Survive 15次左右時,則把這部分剩餘對象放到Old區;
6. 當Old區也被填滿時,進行Major GC,對Old區進行垃圾回收。

   3》新生代採用的GC算法是 複製算法,而老年代採用的是標記-清除算法

  4》複製算法就是 eden區往s0複製,或者往s1複製的過程,默認次數15次

  5》標記-清除算法  是老年區依舊在用的對象標記可可達對象  清除就是清除不可達的對象。    

  拓展:GC觸發條件

 

GC類型 觸發條件 觸發時發生了什麼 注意 查看方式
YGC eden空間不足

清空Eden+from survivor中全部no ref的對象佔用的內存
將eden+from sur中全部存活的對象copy到to sur中
一些對象將晉升到old中:
    to sur放不下的
    存活次數超過turning threshold中的
從新計算tenuring threshold(serial parallel GC會觸發此項)

從新調整Eden 和from的大小(parallel GC會觸發此項)

全過程暫停應用
是否爲多線程處理由具體的GC決定
jstat –gcutil 
gc log
FGC

old空間不足
perm空間不足
顯示調用System.GC, RMI等的定時觸發
YGC時的悲觀策略
dump live的內存信息時(jmap –dump:live)

清空heap中no ref的對象
permgen中已經被卸載的classloader中加載的class信息

如配置了CollectGenOFirst,則先觸發YGC(針對serial GC)
如配置了ScavengeBeforeFullGC,則先觸發YGC(針對serial GC)

全過程暫停應用
是否爲多線程處理由具體的GC決定

是否壓縮須要看配置的具體G

===============================================================

4.你是經過什麼方式實現JVM優化的?

  1》調整新生代、s0、s1比例以及調整新生代 老年代的大小,目的是減小GC次數

  2》不要顯示的調用system.GC()

  3》對象不用的時候顯式的置爲null

  4》儘可能減小局部變量的使用

  5》儘可能使用基本數據類型而不使用封裝類

  6》儘可能少使用靜態變量,由於靜態變量屬於類的變量,是全局變量,會一直佔用資源

  7》儘可能分散的建立對象,不要一次性建立多個對象。

  8》http://www.javashuo.com/article/p-ontvojsr-ga.html

 

===============================================================

5.內存溢出和內存泄漏的區別

http://www.javashuo.com/article/p-mocpeqed-bn.html

 

===============================================================

相關文章
相關標籤/搜索