1. 程式人生 > >JVM記憶體管理及JAVA效能調優相關筆記

JVM記憶體管理及JAVA效能調優相關筆記

JVM篇
1.JVM記憶體分配:方法區、Java棧、本地方法棧、堆、程式計數器
方法區:在方法區中,儲存了每個類的資訊(包括類的名稱、方法資訊、欄位資訊)、靜態變數、常量以及編譯器編譯後的程式碼等。
Java棧:用來儲存方法中的區域性變數(包括在方法中宣告的非靜態變數以及函式形參)。對於基本資料型別的變數,則直接儲存它的值,對於引用型別的變數,則存的是指向物件的引用。區域性變量表的大小在編譯器就可以確定其大小了,因此在程式執行期間區域性變量表的大小是不會改變的。
本地方法棧:在JVM規範中,並沒有對本地方法棧的具體實現方法以及資料結構作強制規定,虛擬機器可以自由實現它。在HotSopt虛擬機器中直接就把本地方法棧和Java棧合二為一。

:Java中的堆是用來儲存物件本身的以及陣列(當然,陣列引用是存放在Java棧中的)。只不過和C語言中的不同,在Java中,程式設計師基本不用去關心空間釋放的問題,Java的垃圾回收機制會自動進行處理。因此這部分空間也是Java垃圾收集器管理的主要區域。另外,堆是被所有執行緒共享的,在JVM中只有一個堆。堆由老年代、年輕代、永久代組成。
程式計數器:雖然JVM中的程式計數器並不像組合語言中的程式計數器一樣是物理概念上的CPU暫存器,但是JVM中的程式計數器的功能跟組合語言中的程式計數器的功能在邏輯上是等同的,也就是說是用來指示 執行哪條指令的。由於程式計數器中儲存的資料所佔空間的大小不會隨程式的執行而發生改變,因此,對於程式計數器是不會發生記憶體溢位現象(OutOfMemory)的。

主要引數設定:
-XMX:JVM的堆最大大小
-XMS:JVM的堆預設大小
以上兩個配置建議保持一致,因為防止每次垃圾回收完成後,JVM重新分配記憶體,容易影響效能
-XMN:Java堆中新生代記憶體大小,老年代的大小為XMX減去它
-XSS:指定執行緒棧大小,對應單個執行緒大小,影響能生成的執行緒數量

2.寬泛的理解JVM的執行過程,JVM啟動,載入底層所有的配置,如執行緒、方法、設定堆大小等,程式先編譯為class檔案,又通過JIT執行時編譯執行程式碼,執行過程中,生成各種物件...,存放於JVM記憶體中,有新生代、老生代、永久代,由JVM管理記憶體,並有垃圾收集器,即GC對個記憶體中的資料進行回收,保證JVM效能。

3.垃圾收集(GC)是一種stop-the-world(時空停滯)操作,即停止所有正在執行的應用執行緒,如果此時系統正在進行頁面互動,則會引起JVM長時間的停頓。

4.Minor GC和Full GC區別
Minor GC,即新生代GC,即發生在新生代的垃圾收集動作,比較頻繁,且回收速度也比較快。
Full GC,即老年代GC,即發生在老年代的垃圾回收動作,次數少,且速度比Minor GC慢10倍以上。

5.Hotspot VM主要有3個元件:VM執行時(Runtime)、JIT編譯器(JIT Compiler)以及記憶體管理器(memory manager)。

6.監控JVM(Hotspot VM)工具:JConsole、visualGC以及visualVM等,當前比較流行的是開源工具 Prometheus(普羅米修斯),感興趣的可以瞭解下,此處忽略。

7.Java垃圾收集器調優,三個需要理解的基本原則:
(1)每次Minor GC都儘可能多地收集垃圾物件;
(2)處理吞吐量和延遲問題時,垃圾處理器能使用的記憶體越大,即Java堆空間越大,垃圾收集的效果越好,應用程式執行也越流暢;
(3)在這三個效能屬性(吞吐量、延遲、記憶體佔用)中,任意選擇兩項進行調優,即為“GC調優的3選2原則”

8.記憶體洩漏:如果一個永遠不再使用的物件,由於等待一個或多個Java物件對它的引用而不能被垃圾收集,就稱之為發生了記憶體洩漏。

JAVA效能調優篇
參考:
Java 效能調優的 11 個實用技巧:http://www.importnew.com/27390.html,個鐘見解比較實用,推薦!
java效能調優實戰:https://www.cnblogs.com/objJava/p/9035355.html,通過伺服器端使用top等命令找出比較消耗資源的執行緒,並把該執行緒對應執行的程式dump出來,用來定位分析問題。