一.jvm內存模型:
1. Java棧: 邏輯單位,存儲對象引用,變量值,基本數據類型(長度固定)
2. Java堆: 年輕代(伊甸區/倖存區1/倖存區2),老年代(可變對象長度),8的整數倍byte。
1) full gc整個堆掃
2) minor gc只是年輕代
3) 因爲大部分對象都是從Eden區開始的,同時Eden區不會分配的很大,所以Eden區的GC會頻繁進行。因而,一般在這裏需要使用速度快、效率高的算法,使Eden去能儘快空閒出來。
4)年老代有一個"card table",記錄年老代指向新生代的對象引用。新生代回收時只需要查詢年老代該table就可以。加快速度
5) 大對象,長期存活的對象進入老年代
3. 方法區: 靜態變量,常量(字符串)
二.基本回收算法:
按策略:
1.引用計數: 有引用加一,刪除引用減一。回收引用爲0的對象。無法回收循環引用對象
2.複製: 需要兩倍空間,一個滿了將正在使用的對象複製到另一個空間。不會出現碎片問題
3.標記清除: 首先由根節點開始,標記被引用對象,然後回收未被引用的。會暫停以及產生內存碎片
4.標記清理: 首先由根節點標記所有被引用對象。然後清除未標記對象,並壓縮在一起
按線程:
1.串行: 單CPU
2.並行: 多線程收集,需要暫停運行環境。堆空間大的時候,回收的時間也變長。適用於對吞吐量有要求的。比如後臺計算程序
-XX:+UseParallelGC.打開。
-XX:ParallelGCThreads=<N>設置並行垃圾回收的線程數。此值可以設置與機器處理器數量相等。
-XX:MaxGCPauseMillis=<N>指定。<N>爲毫秒.如果指定了此值的話,堆大小和垃圾回收相關參數會進行調整以達到指定值。設定此值可能會減少應用的吞吐量。
吞吐量:吞吐量爲垃圾回收時間與非垃圾回收時間的比值,通過 -XX:GCTimeRatio=<N>來設定,公式爲1/(1+N)。
3.併發: 不停頓。可以保證大部分工作都併發進行(應用不停止)。會產生浮動垃圾,必須要清理完之前保證老年代沒有滿。對響應時間有要求的。Web服務器
XX:+UseConcMarkSweepGC打開。
-XX:CMSInitiatingOccupancyFraction=<N>指定還有多少剩餘堆時開始執行併發收集。併發收集器一般需要20%的預留空間用於這些浮動垃圾。
三. 內存泄漏幾種情況:
1. Java heap space: 年老代滿了。找到回收後殘餘對象,然後分析
2. PermGen space: 持久代滿了。 Java大量反射導致class文件太多
四.常用調優參數:
1) -xx:NewRatio: 指定新生代和老年代大小比例.基本上是新:老=1:2=3:8
2)
五. 查詢命令:
1. dump內存快照 /usr/java/jdk1.6.0_29/bin/./jmap -dump:format=b,file=/dev/shm/dump.bin -F 18188
2. 查看堆內存對象數量,大小: jmap -histo pid
3. 查看堆使用情況: jmap -heap pid
4. 打印給定進程id 的堆棧信息: jstack [ option ] pid
5. 發現死鎖: jstack -l pid 兩個線程互相locked而且等待對方的某個資源(號一樣)