手记

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。

4人推荐
随时随地看视频
慕课网APP