本文主要為《深入理解JVM虛擬機器》一書的閱讀筆記
1. Java堆記憶體上限溢位
在生產環境中,常常遇到各種Java記憶體問題,在分析JVM記憶體時,可以考慮使用MAT。在閱讀《深入理解JVM記憶體》一書時,有如下一個例子:
/**
* VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
*/
public class HeapOOM {
static class OOMObject {
}
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<>();
while (true) {
list.add(new OOMObject());
}
}
}
在遇到“java.lang.OutOfMemoryError”錯誤時,首先需要根據MAT工具確認是記憶體洩漏還是記憶體上限溢位。
2. JVM引數
關於JVM記憶體,有幾個常用的標誌:-Xmn表示年輕代大小;-Xmx表示JVM的最大可用堆記憶體;-Xms表示JVM的最小可用堆記憶體;-Xss表示執行緒棧大小。
3. 識別要回收的記憶體
在JVM記憶體回收中,要識別哪些記憶體需要回收,一般有兩種方法判斷某個物件的使用狀態:取用計數和可達性分析演演算法,在JVM中使用“可達性分析演演算法”進行管理。在Java語言中,可作為GC Roots的物件包括以下幾種:
-虛擬機器棧(棧幀中的本地變數表)中取用的物件;
-方法區中類靜態屬性取用的物件;
-方法區中常量取用的物件;
-本地方法棧中JNI(即一般說的Native方法)取用的物件;
4. 關於JVM中的finalize()方法
-
finalize()方法是物件逃脫死亡的最後一次機會;
-
一個物件的finalize()方法最多隻會被系統自動呼叫一次;
-
finalize()方法的執行代價高昂,不確定性大,無法保證各個物件的呼叫順序。
-
finalize()方法能做的所有工作,使用try-finally或其他方式都可以做得更好、更及時,所以我們最好忘記這個方法的存在;
5. 垃圾回收演演算法
標記—清除演演算法、標記—複製演演算法、標記—整理演演算法和分代回收演演算法,思路是層層遞進的,標記—清除演演算法是基本思路,後續的演演算法都是為瞭解決這種基本思路的缺點而發展出來的。
6. 幾種垃圾收集器的選擇
(1)在吞吐量優先/CPU資源寶貴的場景下,適合使用Parallel Scanvenge收集器(年輕代) + Parallel Old收集器(老年代)組合;(2)在響應時間敏感的Web服務場景下,適合使用ParalNew(年輕代) + CMS(老年代)組合,在這種情況下還有Serial Old作為CMS出錯時的備份;(3)在client樣式下的客戶端應用場景下,JVM記憶體不多,序列蒐集器效率高、沒有多執行緒開銷,適合使用Serial收集器。
7. JVM調優總結文章
連結:http://unixboy.iteye.com/blog/174173
8. Java序列化包括的知識點
(1)ObjectOutputStream和ObjectInputStream連個類的writeObject()/readObject()方法;(2)序列化/反序列化是Java物件與位元組流之間的轉換過程;(3)序列化生成的檔案具備指定的格式,包含了恢復Java物件需要的全部資訊;(4)對於不想/不能序列化的欄位,使用transient修飾;(5)每個物件都有一個序列號,相同物件的重覆會被儲存為這個序列號的取用;(6)透過重寫readObject/writeObject可以針對某些域進行驗證;(7)透過實現Externalizable介面可以完全重寫序列化機制;(8)舊程式碼中的單例設計樣式和自己實現的列舉型別,需要實現readResolve()方法,修複bug。
最後做個投票,這個號後面的發展,有你的一份努力: