21.類加載的過程
-
加載:java將字節碼數據從不同的數據源讀取都jvm中,並映射爲jvm認可的數據結構,數據源可以是class,jar,網絡資源等
-
鏈接:
- 驗證:jvm檢驗字節信息是否符合jvm規範
- 準備:創建類或者接口中的靜態變量,並初始化靜態變量的值。(主要是分配內存空間)
- 解析:將常量池中的符號引用替換爲直接引用。
-
初始化:執行類的初始化邏輯,包括靜態字段的賦值動作。
22.jvm內存區域的劃分
程序計數器 | 線程私有 | 記錄程序執行到哪一步了 |
---|---|---|
虛擬機棧 | 線程私有 | 入棧和出棧操作,記錄程序執行到哪個方法了 |
堆內存 | 線程共享,進程私有 | 幾乎所有的創建的對象存放的地方,也是垃圾回收期主要管理的區域 |
方法區 | 線程共享區域 | 存儲元數據,例如:類結構信息,運行時常量池,字段,方法代碼等。老版的永久代的數據也遷移到此處 |
運行時常量池 | 方法區的一部分 | 存放各種常量信息 |
本地方法棧 | 線程私有 | 但是在Oracle的HotSpot虛擬機中,和虛擬機棧合併 |
23.容易發生OOM(OutOfMemeory)的區域
-
直接內存DirectBuffer,堆外內存。比較難以檢測
-
堆內存不足,可能是內存泄漏,或者說是內存設定的值偏小
-
java棧循環遞歸,超過棧允許的深度。或者擴展棧空間的時候失敗。
-
MetaSpace區域內存溢出
24.監控和診斷Jvm堆內存
-
使用JConsole或者JVisualVM在圖形化界面查看
-
使用堆的dump文件來查看內存使用情況
-
Jmap、jstat命令也可以查看
-
Tomcat 和Weblogic等web容器都提供了內存管理功能
-
查看GC日誌
24.Jvm堆內存模型
Eden | 新生代 | 新生成的對象,GC主要的回收區域 |
---|---|---|
Sfrom | 年輕代 | 經過較少次數的Gc但是沒有被回收掉的對象 |
Sto | 年輕代 | 和Sfrom區域相互切換的區域 |
Old | 老年代 | 經過多次Gc沒有被回收掉的對象 |
Tlab | 線程私有的新生代 | 放置線程私有的對象,可以通過jvm參數關閉 |
年輕代回收次數默認閥值爲16次
25.談談你的GC調優思路
GC 調優一般關注三個方面:內存佔用、延時、吞吐量。一般情況下都是針對其中一個點或者兩個點來優化,很少三者兼顧。
常用的思路爲:
- 理解應用的需求和問題,確定調優目標。例如減少GC停頓,那麼停頓減少到多少合適200ms還是10ms
- 掌握JVM和GC的狀態,定位具體問題。針對JVM的運行狀態,內存佔用情況等。
- 選擇的GC類型是否合適,是否要更換垃圾收集器
- 確定軟硬件的各種參數
- 驗證結果是否達到期望目標
26.後臺服務突然變慢怎麼解決
- 是突然變慢還是慢慢變慢的
- 問題是來源於程序自身還是源於對別的程序的依賴。
- 監控自身服務,查看服務自身的一些信息是否正常