歡迎光臨
每天分享高質量文章

Java Web技術經驗總結(十)

本文主要為《深入理解JVM虛擬機》一書的閱讀筆記

1. Java堆記憶體上限溢位

在生產環境中,常常遇到各種Java記憶體問題,在分析JVM記憶體時,可以考慮使用MAT。在閱讀《深入理解JVM記憶體》一書時,有如下一個例子:

  1. /**

  2. * VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

  3. */

  4. public class HeapOOM {

  5.    static class OOMObject {

  6.    }

  7.    public static void main(String[] args) {

  8.        List<OOMObject> list = new ArrayList<>();

  9.        while (true) {

  10.            list.add(new OOMObject());

  11.        }

  12.    }

  13. }

在遇到“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。


最後做個投票,這個號後面的發展,有你的一份努力:

赞(0)

分享創造快樂