首页 > 技术文章 > JVM GC 基础原理

shay 2020-06-18 16:42 原文

 

  • GC基础原理,涉及调优目标,GC事件分类、JVM内存分配策略、GC日志分析等
  • java的最大好处是自动垃圾回收,这样就无需我们手动的释放对象空间了,但是也产生了相应的负效果,gc是需要时间和资源的,不好的gc会严重影响系统的性能,因此良好的gc是JVM的高性能的保证。 

  • 1 GC调优目标
  • 大多数情况下对 Java 程序进行GC调优, 主要关注两个目标:响应速度、吞吐量

    • 响应速度(Responsiveness) 响应速度指程序或系统对一个请求的响应有多迅速。比如,用户订单查询响应时间,对响应速度要求很高的系统,较大的停顿时间是不可接受的。调优的重点是在短的时间内快速响应

    • 吞吐量(Throughput) 吞吐量关注在一个特定时间段内应用系统的最大工作量,例如每小时批处理系统能完成的任务数量,在吞吐量方面优化的系统,较长的GC停顿时间也是可以接受的,因为高吞吐量应用更关心的是如何尽可能快地完成整个任务,不考虑快速响应用户请求

    GC调优中,GC导致的应用暂停时间影响系统响应速度,GC处理线程的CPU使用率影响系统吞吐量

    2 GC分代收集算法

    现代的垃圾收集器基本都是采用分代收集算法,其主要思想: 将Java的堆内存逻辑上分成两块:新生代、老年代,针对不同存活周期、不同大小的对象采取不同的垃圾回收策略

    分代收集算法
    • 新生代(Young Generation)

    新生代又叫年轻代,大多数对象在新生代中被创建,很多对象的生命周期很短。每次新生代的垃圾回收(又称Young GC、Minor GC、YGC)后只有少量对象存活,所以使用复制算法,只需少量的复制操作成本就可以完成回收

    新生代内又分三个区:一个Eden区,两个Survivor区(S0、S1,又称From Survivor、To Survivor),大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到两个Survivor区(中的一个)。当这个Survivor区满时,此区的存活且不满足晋升到老年代条件的对象将被复制到另外一个Survivor区。对象每经历一次复制,年龄加1,达到晋升年龄阈值后,转移到老年代

    • 老年代(Old Generation)

    在新生代中经历了N次垃圾回收后仍然存活的对象,就会被放到老年代,该区域中对象存活率高。老年代的垃圾回收通常使用“标记-整理”算法

    3 GC事件分类

    根据垃圾收集回收的区域不同,垃圾收集主要通常分为Young GC、Old GC、Full GC、Mixed GC

    (1) Young GC

    新生代内存的垃圾收集事件称为Young GC(又称Minor GC),当JVM无法为新对象分配在新生代内存空间时总会触发 Young GC,比如 Eden 区占满时。新对象分配频率越高, Young GC 的频率就越高

    Young GC 每次都会引起全线停顿(Stop-The-World),暂停所有的应用线程,停顿时间相对老年代GC的造成的停顿,几乎可以忽略不计

    (2) Old GC 、Full GC、Mixed GC

    Old GC,只清理老年代空间的GC事件,只有CMS的并发收集是这个模式 Full GC,清理整个堆的GC事件,包括新生代、老年代、元空间等

    Mixed GC,清理整个新生代以及部分老年代的GC,只有G1有这个模式

     

    4 GC日志分析

    GC日志是一个很重要的工具,它准确记录了每一次的GC的执行时间和执行结果,通过分析GC日志可以调优堆设置和GC设置,或者改进应用程序的对象分配模式,开启的JVM启动参数如下:

    -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps  -XX:+PrintGCTimeStamps

    常见的Young GC、Full GC日志含义如下:

    Young GCFull GC

    免费的GC日志图形分析工具推荐下面2个:

    • GCViewer,下载jar包直接运行
    • gceasy,web工具,上传GC日志在线使用

    5 内存分配策略

     

     

推荐阅读