1. 程式人生 > >jvm的幾個概念誤區

jvm的幾個概念誤區

serial old是一種垃圾回收器

serial old其實表示的是一種說法,老年代單執行緒回收。在不同的垃圾回收器中實現各部相同,現在有以下幾種實現g1MarkSweep,psMarkSweep,genMarkSweep。

parallel gc日誌裡的老年代名稱有時候會變

其實是老年代回收器不一樣。 老年代回收器為psMarkSweep的是叫PSOldGen。 老年代回收器為psParallelCompact的是叫ParOldGen。 每個版本的jvm預設垃圾回收演算法不一樣,如果預設是-XX:+UseParallelOldGC,你自己雖然設定了-XX:+UseParallelGC。但是也會有是加了-XX:+UseParallelOldGC的效果。

full gc其實是minor gc,然後執行old gc。

其實full gc就是fullgc。是區別於minor gc,old gc。

full gc的演算法其實很多

準確來說真的只有一種。標記-清除-壓縮。實現是有多種的。

cms的backgroud gc的時候只回收老年代。

這個也是有引數控制的。CMSScavengeBeforeRemark,預設是關閉的。

survivor 某個年齡物件達到survivor 區域的50%就發生晉升。

50%其實是一個引數控制的,TargetSurvivorRatio。預設50。 並不是某個年齡的物件大小達到。找出從1開始,累加和超過TargetSurvivorRatio的比值的那個年齡。從那個年齡開始以上的物件有資格晉升。需要和MaxTenuringThreshold對比找到最小的那個年齡。

物件優先生成在eden

其實最優先的應該是棧上分配,其次是tlab(eden的一部分),然後嘗試大物件直接嘗試老年代的邏輯,如果不滿足,則在eden上分配。

直接記憶體和元資料區有關係

元資料區(1.6永久帶)概念上是非堆。直接記憶體是另外的區域,nio申請的就是這裡的,有引數控制大小-XX:MaxDirectMemorySize,預設和堆的記憶體一樣大,並且和jni用的記憶體概念上也不是一回事。

parallel gc的時候就是先執行一次minor gc,然後再old gc。

這是有個引數ScavengeBeforeFullGC老控制的。預設是開啟的,日誌內容輸出如下

[GC (System.gc()) [PSYoungGen: 1843K->776K(35840K)] 1843K->784K(117760K), 0.0022147 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (System.gc()) [PSYoungGen: 776K->0K(35840K)] [ParOldGen: 8K->637K(81920K)] 784K->637K(117760K), [Metaspace: 2658K->2658K(1056768K)], 0.0091183 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

當關閉掉的時候日誌如下

[Full GC (System.gc()) [PSYoungGen: 1843K->0K(35840K)] [ParOldGen: 0K->637K(81920K)] 1843K->637K(117760K), [Metaspace: 2658K->2658K(1056768K)], 0.0101733 secs] [Times: user=0.03 sys=0.01, real=0.01 secs]

區別就是少了那次minor gc。而且後面都是fullgc。並不是old gc。