面試大全之JVM篇

JVM

  1. 內存模型以及分區,須要詳細到每一個區放什麼。

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

new:算法

  • 方法區:主要是存儲類信息,常量池(static常量和static變量),編譯後的代碼(字節碼)等數據
  • 堆:初始化的對象,成員變量 (那種非static的變量),全部的對象實例和數組都要在堆上分配
  • 棧:棧的結構是棧幀組成的,調用一個方法就壓入一幀,幀上面存儲局部變量表,操做數棧,方法出口等信息,局部變量表存放的是8大基礎類型加上一個應用類型,因此仍是一個指向地址的指針
  • 本地方法棧:主要爲Native方法服務
  • 程序計數器:記錄當前線程執行的行號
  1. 堆裏面的分區:Eden,survival (from+ to),老年代,各自的特色。

堆裏面分爲新生代和老生代(java8取消了永久代,採用了Metaspace),新生代包含Eden+Survivor區,survivor區裏面分爲from和to區,內存回收時,若是用的是複製算法,從from複製到to,當通過一次或者屢次GC以後,存活下來的對象會被移動到老年區,當JVM內存不夠用的時候,會觸發Full GC,清理JVM老年區數組

當新生區滿了以後會觸發YGC,先把存活的對象放到其中一個Survice
區,而後進行垃圾清理。由於若是僅僅清理須要刪除的對象,這樣會致使內存碎
片,所以通常會把Eden 進行徹底的清理,而後整理內存。那麼下次GC 的時候,
就會使用下一個Survive,這樣循環使用。若是有特別大的對象,新生代放不下,
就會使用老年代的擔保,直接放到老年代裏面。由於JVM 認爲,通常大對象的存
活時間通常比較久遠。多線程

  1. 對象建立方法,對象的內存分配,對象的訪問定位。

new 一個對象app

  1. GC的兩種斷定方法:

引用計數法:指的是若是某個地方引用了這個對象就+1,若是失效了就-1,當爲0就會回收可是JVM沒有用這種方式,由於沒法斷定相互循環引用(A引用B,B引用A)的狀況eclipse

引用鏈法: 經過一種GC ROOT的對象(方法區中靜態變量引用的對象等-static變量)來判斷,若是有一條鏈可以到達GC ROOT就說明,不能到達GC ROOT就說明能夠回收jvm

  1. SafePoint是什麼

好比GC的時候必需要等到Java線程都進入到safepoint的時候VMThread才能開始執行GC,工具

  1. 循環的末尾 (防止大循環的時候一直不進入safepoint,而其餘線程在等待它進入safepoint)
  2. 方法返回前
  3. 調用方法的call以後
  4. 拋出異常的位置
  1. GC的三種收集方法:標記清除、標記整理、複製算法的原理與特色,分別用在什麼地方,若是讓你優化收集方法,有什麼思路?

先標記,標記完畢以後再清除,效率不高,會產生碎片性能

複製算法:分爲8:1的Eden區和survivor區,就是上面談到的YGC優化

標記整理:標記完畢以後,讓全部存活的對象向一端移動

  1. GC收集器有哪些?CMS收集器與G1收集器的特色。

並行收集器:串行收集器使用一個單獨的線程進行收集,GC時服務有停頓時間

串行收集器:次要回收中使用多線程來執行

CMS收集器是基於「標記—清除」算法實現的,通過屢次標記纔會被清除

G1從總體來看是基於「標記—整理」算法實現的收集器,從局部(兩個Region之間)上來看是基於「複製」算法實現的

[GC收集器]: http://www.jianshu.com/p/50d5c88b272d

  1. Minor GC與Full GC分別在何時發生?

新生代內存不夠用時候發生MGC也叫YGC,JVM內存不夠的時候發生FGC

  1. 幾種經常使用的內存調試工具:jmap、jstack、jconsole、jhat

jstack能夠看當前棧的狀況,jmap查看內存,jhat 進行dump堆的信息

mat(eclipse的也要了解一下)

  1. 類加載的幾個過程:

加載、驗證、準備、解析、初始化。而後是使用和卸載了

經過全限定名來加載生成class對象到內存中,而後進行驗證這個class文件,包括文件格式校驗、元數據驗證,字節碼校驗等。準備是對這個對象分配內存。解析是將符號引用轉化爲直接引用(指針引用),初始化就是開始執行構造器的代碼

  1. 雙親委派模型:Bootstrap ClassLoader、Extension ClassLoader、ApplicationClassLoader。

Bootstrap ClassLoader:啓動類加載器,負責將$ Java_Home/lib下面的類庫加載到內存中(好比rt.jar

Extension ClassLoader:標準擴展(Extension)類加載器,它負責將$Java_Home /lib/ext或者由系統變量 java.ext.dir指定位置中的類庫加載到內存中。

ApplicationClassLoader:它負責將系統類路徑(CLASSPATH)中指定的類庫加載到內存中。開發者能夠直接使用系統類加載器

雙親委派模型是某個特定的類加載器在接到加載類的請求時,首先將加載任務委託給父類加載器,依次遞歸,若是父類加載器能夠完成類加載任務,就成功返回;只有父類加載器沒法完成此加載任務時,才本身去加載。-----例如類java.lang.Object,它存在在rt.jar中,不管哪個類加載器要加載這個類,最終都是委派給處於模型最頂端的Bootstrap ClassLoader進行加載,所以Object類在程序的各類類加載器環境中都是同一個類。相反,若是沒有雙親委派模型而是由各個類加載器自行加載的話,若是用戶編寫了一個java.lang.Object的同名類並放在ClassPath中,那系統中將會出現多個不一樣的Object類,程序將混亂

  1. 分派

靜態分派(重載)與動態分派(重寫)。

  1. 你知道哪些JVM性能調優

設定堆最小內存大小-Xms

  1. -Xmx:堆內存最大限制。
  2. 設定新生代大小。
    新生代不宜過小,不然會有大量對象涌入老年代

-XX:NewSize:新生代大小

-XX:NewRatio 新生代和老生代佔比

-XX:SurvivorRatio:伊甸園空間和倖存者空間的佔比

  1. 設定垃圾回收器

​ 年輕代用 -XX:+UseParNewGC (串行) 年老代用-XX:+UseConcMarkSweepGC (CMS)

  1. 設定鎖的使用

多線程下關閉偏向鎖,比較浪費資源

  1. g1 和 cms 區別,吞吐量優先和響應優先的垃圾收集器選擇

1CMS是一種以最短停頓時間爲目標的收集器

響應優先選擇CMS,吞吐量高選擇G1

  1. 當出現了內存溢出,你怎麼排錯

用jmap看內存狀況,而後用 jstack主要用來查看某個Java進程內的線程堆棧信息

  1. JVM內存模型的相關知識瞭解多少

JVM內存結構扯一下

相關文章
相關標籤/搜索