HotSpot和堆
- 堆
Heap,一個JVM只有一個堆內存,堆內存的大小是可以調節的
類加載器讀取了類文件之後,一般會把什麼放到堆中?
類,方法,常量,變量,保存我們所有引用類型的真實對象。 - 堆內存還要細分爲三個區域
- 新生區(伊甸園區)
- 養老區
- 永久區
-
GC垃圾回收,主要是在伊甸園區和養老區
假設內存滿了,OOM,堆內存不夠,java.lang.OutOfMemoryError: java heap space
在jdk8之後,永久存儲區改了個名字(元空間)。 -
新生區
類誕生,成長,甚至死亡的地方
- 伊甸園區 所有的對象都是在伊甸園區new出來的
- 倖存者區(0,1)
- 真理,經過研究,99%的對象就是臨時對象。
- 永久區
這個區域常駐內存,用來存放JDK自身攜帶的Class對象,Interface元數據,存儲的是java運行時的一些環境或者類信息,這個區域不存在垃圾回收,關閉JVM虛擬機會釋放這個區域的內存。
一個啓動類,加載了大量的第三方jar包,Tomcat部署了太多的應用,大量動態生成的反射類,不斷地被加載,直到內存滿,就會出現OOM
對象生命週期和GC
倖存區0–S0—from
倖存區1–S1—to
from區和to區,他們的位置和名分不是固定的(都只佔新生代區的1/10),每次GC後會交換
也就是說:GC之後有交換,誰空誰是to
- 只要產生GC,伊甸園區必須全部清空
堆內存調優
- 默認情況下,分配的總內存,是電腦的1/4,而初始化的內存是1/16
- 在配置中修改參數語句:
-Xms1024m -Xmx1024m -XX:+PrintGCDetails
使用Jprofiler工具分析OOM原因
- 在一個項目中,突然出現OOM故障,那麼該如何排查錯誤?
- 能夠看到代碼第幾行出錯:內存快照分析工具,MAT,Jprofiler工具
- Dubug,一行行分析代碼。
MAT,Jprofiler作用
- 分析Dump文件,快速定位內存泄漏
-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
-Xms 設置初始化內存分配大小
-Xmx 設置最大分配內存,默認1/4
-XX:+PrintGCDetails 打印GC垃圾回收信息
-XX:+HeapDumpOnOutOfMemoryError
- 獲得堆中的數據
- 獲得大的對象