gzyueqian
13352868059

看java工程师怎么点破jvm的几个概念误区-java技术分享

更新时间: 2018-10-06 12:00:00来源: Java培训浏览量:2020

    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。

    想要了解更多的java应用技术那家加入我们吧!

免费预约试听课