GC ( Java)

作者: 雨笋情缘 | 来源:发表于2017-08-24 14:07 被阅读28次

    1、GC相关的参数:

    -Xms / -Xmx — 堆的初始大小 / 堆的最大大小

    -Xmn — 堆中年轻代的大小

    -XX:-DisableExplicitGC — 让System.gc()不产生任何作用

    -XX:+PrintGCDetails — 打印GC的细节

    -XX:+PrintGCDateStamps — 打印GC操作的时间戳

    -XX:NewSize / XX:MaxNewSize — 设置新生代大小/新生代最大大小

    -XX:NewRatio — 可以设置老生代和新生代的比例

    -XX:PrintTenuringDistribution — 设置每次新生代GC后输出幸存者乐园中对象年龄的分布

    -XX:InitialTenuringThreshold / -XX:MaxTenuringThreshold:设置老年代阀值的初始值和最大值

    -XX:TargetSurvivorRatio:设置幸存区的目标使用率

    2、GC回收器类型

            JVM中的垃圾收集一般都采用“分代收集”,不同的堆内存区域采用不同的收集算法,主要目的就是为了增加吞吐量或降低停顿时间。

    Serial收集器:新生代收集器,使用复制算法,使用一个线程进行GC,串行,其它工作线程暂停。

    ParNew收集器:新生代收集器,使用复制算法,Serial收集器的多线程版,用多个线程进行GC,并行,其它工作线程暂停。使用-XX:+UseParNewGC开关来控制使用ParNew+Serial Old收集器组合收集内存;使用-XX:ParallelGCThreads来设置执行内存回收的线程数。

    Parallel Scavenge 收集器

            吞吐量优先的垃圾回收器,作用在新生代,使用复制算法,关注CPU吞吐量,即运行用户代码的时间/总时间。使用-XX:+UseParallelGC开关控制使用Parallel Scavenge+Serial Old收集器组合回收垃圾。

    Serial Old收集器

            老年代收集器,单线程收集器,串行,使用标记整理算法,使用单线程进行GC,其它工作线程暂停。

    Parallel Old收集器

            吞吐量优先的垃圾回收器,作用在老年代,多线程,并行,多线程机制与Parallel Scavenge差不错,使用标记整理算法,在Parallel Old执行时,仍然需要暂停其它线程。

    CMS(Concurrent Mark Sweep)收集器

           老年代收集器,致力于获取最短回收停顿时间(即缩短垃圾回收的时间),使用标记清除算法,多线程,优点是并发收集(用户线程可以和GC线程同时工作),停顿小。使用-XX:+UseConcMarkSweepGC进行ParNew+CMS+Serial Old进行内存回收,优先使用ParNew+CMS(原因见Full GC和并发垃圾回收一节),当用户线程内存不足时,采用备用方案Serial Old收集。

    3、Full GC

            并发垃圾回收器的内存回收过程是与用户线程一起并发执行的。通常情况下,并发垃圾回收器可以在用户线程运行的情况下完成大部分的回收工作,所以应用停顿时间很短。

            但由于并发垃圾回收时用户线程还在运行,所以会有新的垃圾不断产生。作为担保,如果在老年代内存都被占用之前,如果并发垃圾回收器还没结束工作,那么应用会暂停,在所有用户线程停止的情况下完成回收。这种情况称作Full GC,这意味着需要调整有关并发回收的参数了。

            由于Full GC很影响应用的性能,要尽量避免或减少。特别是如果对于高容量低延迟的电商系统,要尽量避免在交易时间段发生Full GC。

    4、总结

    (1)为了分代垃圾回收,Java堆内存分为3代:新生代,老年代和永久代。

    (2)新的对象实例会优先分配在新生代,在经历几次Minor GC后(默认15次),还存活的会被移至老年代(某些大对象会直接在老年代分配)。

    (3)永久代是否执行GC,取决于采用的JVM。Java中不能手动触发GC,但可以用不同的引用类来辅助垃圾回收器工作(比如:弱引用或软引用)。

    (4)Minor GC发生在新生代,当Eden区没有足够空间时,会发起一次Minor GC,将Eden区中的存活对象移至Survivor区。Major GC发生在老年代,当升到老年代的对象大于老年代剩余空间时会发生Major GC。

    (5)发生Major GC时,用户线程会暂停,会降低系统性能和吞吐量。

    (6)JVM中Java堆内存的初始大小和最大值,依据个人经验这个值的比例最好是1:1或者1:1.5。比如,你可以将-Xmx和-Xms都设为1GB,或者-Xmx和-Xms设为1.8GB和1.2GB。

    参考文献:https://yemengying.com/2016/05/13/jvm-GC/

    相关文章

      网友评论

        本文标题:GC ( Java)

        本文链接:https://www.haomeiwen.com/subject/kkqedxtx.html