JVM大體結構
class 文件 加載-驗證-準備-解析-初始化-使用-卸載 一個線程一個棧,一個方法一個棧幀
如何確定垃圾
- 引用計數
- 會有循環引用的問題
- 正向可達
- 從roots對象計數可以達到的對象
垃圾收集算法
-
標記清除(缺點:內存碎片化,沒有連續的內存)
-
Copying (缺點:浪費內存 一般用在新生代[new])
-
標記壓縮 (比copying慢一點 一般用在老年代[tenured])
-
new
- 存活對象少
- 使用copying,佔用的內存空間也不大,效率也高
-
old
- 垃圾少
- 一般使用mark-compact
瞭解一下上一篇《垃圾收集器》
- Serial Collector
- XX:+UseSerialGC
- 單線程
- Parallel Collector
- 並行量大,不過每次垃圾收集,JVM會停頓
- CMS Collector
- 併發分區來完成,停頓時間短
- G1
- 不僅停頓短,同事併發大。僅僅是個平衡點
- 有人說建議Java9用這個
JVM 參數
- - 標準參數,所有jvm 都應該支持
- -X 非標,每一個jvm實現都不同
- -XX 不穩定參數,下一個版本可能會取消
java 對象的分配
不開逃逸分析不會先分配在棧上
-
棧上分配
- 線程私有小對象
- 無逃逸(-XX:+DoEscapeAnalysis開啓逃逸分析 默認是開啓的)
- 支持標量替換
- 無需調整
-
線程本地分配TLAB(Thread Locla Allacation Buffer)在堆上也是eden區,這樣做的目的是有一部分數據可以不加鎖
- 佔用eden,默認1%
- 多線程的時候不用競爭eden就可以申請空間,提高效率
- 小對象
- 無需調整
-
老年代
- 大對象
-
eden
-
堆:
-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=tmp/jvm.dump -XX:PrintGCDetails
-Xms10M -Xmx10M 直接調大最大,避免中途分析和垃圾回收的計算 -
棧 +Xss128k
大 線程遞歸調用可以很深
小 線程併發數量可以特別多