jvm面試問題及我的答案

今天在技術羣裏被大佬問了一堆jvm的問題。。收集記錄下來。。並且附上我的答案(沒有百度的,不可盡信,僅僅是我看《深入理解java虛擬機》的粗淺回答)

 

1、堆被分成了新生代和老年代,什麼對象會進入老年代。

答:

(1)大對象(對象大小超過設定的閾值),直接到老年代。

(2)在年輕代survivor區域存活minor gc次數超過指定次數的對象。默認是15次。可通過參數設置。

(3)survivor中存活的對象,存活次數相同的對象內存總和大小超過survivor的一半,那麼大於等於這個存活次數的對象都會進入到老年代。

2、如何判斷對象是否可回收?

(1)根據GC roots 進行可達性分析。

 

3、哪些對象可以做GC roots?

(1)、虛擬機棧中的每個棧幀中的局部變量表中的對象(即正在被調用的方法中的局部變量)

(2)、方法區中靜態變量

(3)、方法區運行時常量池裏的引用類型常量。(運行時常量池除了String和其他基本類型的包裝類,還有啥引用類型?而String和包裝類是不可變的啊)

(4)、本地方法棧中使用的對象。(這個不懂)

 

4、如何解決內存泄漏?

這個就要好好利用jdk本身提供的jmap工具了。

(1)用jmap把堆的當前快照文件拿到。

(2)使用專門的工具解析這個快照文件,貌似jdk裏也有一個工具可以簡單解析,轉爲圖形界面。

(3)使用jmap本身參數可以查看佔用內存對象。

(4)定位到具體代碼,然後修改代碼。

5、死鎖如何解決?

使用jstack工具可以查詢當前堆棧信息,並且會判斷死鎖標識。。

阿里開源的arthas也可以查看。。

 

6、觸發gc的條件有哪些?

(1)年輕代內存不夠了,觸發minor GC

(2)老年代內存不夠了,觸發full GC/major GC

(3)方法區(永久代)內存不夠了,觸發Full GC

(4)minor GC時,如果有存活對象要晉升到老年代,如果老年代剩餘空間大小小於歷次平均晉升的對象大小,那麼老年代會進行GC,此時是Full GC。

(5)代碼中使用System.gc,會建議垃圾收集進行GC,但GC不一定聽取建議。。不過在滿足某些條件時還是會聽取建議的(項目中一般不顯示這麼調用,本來就不一定立即生效)

(6)所謂大對象,是指需要大量連續內存空間的java對象,例如很長的數組,此種對象會直接進入老年代,而老年代雖然有很大的剩餘空間,但是無法找到足夠大的連續空間來分配給當前對象,此種情況就會觸發JVM進行Full GC。

 

 

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