Java GC就是JVM记录仪,书画了JVM各个分区的表演。

什么是 Java GC

Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题,也不需要像C程序员那样战战兢兢。这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制。概括地说,该机制对JVM(Java Virtual Machine)中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,永不停息(Nerver Stop)的保证JVM中的内存空间,防止出现内存泄露和溢出问题。

在Java语言出现之前,就有GC机制的存在,如Lisp语言),Java GC机制已经日臻完善,几乎可以自动的为我们做绝大多数的事情。然而,如果我们从事较大型的应用软件开发,曾经出现过内存优化的需求,就必定要研究Java GC机制。

简单总结一下,Java GC就是通过GC收集器回收不在存活的对象,保证JVM更加高效的运转。如果不了解GC算法和垃圾回收器可以参考这篇文章:jvm系列(三):GC算法 垃圾收集器。

如何获取 Java GC日志

一般情况可以通过两种方式来获取GC日志,一种是使用命令动态查看,一种是在容器中设置相关参数打印GC日志。

命令动态查看

Java 自动的工具行命令,jstat可以用来动态监控JVM内存的使用,统计垃圾回收的各项信息。

比如常用命令,jstat -gc统计垃圾回收堆的行为

$ jstat -gc 1262S0C    S1C     S0U     S1U   EC       EU        OC         OU        PC       PU         YGC    YGCT    FGC    FGCT     GCT
26112.0 24064.0 6562.5  0.0   564224.0 76274.5   434176.0   388518.3  524288.0 42724.7    320    6.417   1      0.398    6.815

也可以设置间隔固定时间来打印:

$ jstat -gc 1262 2000 20

这个命令意思就是每隔2000ms输出1262的gc情况,一共输出20次

更详细的内容参考这篇文章:jvm系列(四):jvm调优-命令篇

GC参数

JVM的GC日志的主要参数包括如下几个:

  • -XX:+PrintGC输出GC日志
  • -XX:+PrintGCDetails输出GC的详细日志
  • -XX:+PrintGCTimeStamps输出GC的时间戳(以基准时间的形式)
  • -XX:+PrintGCDateStamps输出GC的时间戳(以日期的形式,如 2017-09-04T21:53:59.234+0800)
  • -XX:+PrintHeapAtGC在进行GC的前后打印出堆的信息
  • -Xloggc:../logs/gc.log日志文件的输出路径

在生产环境中,根据需要配置相应的参数来监控JVM运行情况。

Tomcat 设置示例

我们经常在tomcat的启动参数中添加JVM相关参数,这里有一个典型的示例:

JAVA_OPTS="-server -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m -XX:SurvivorRatio=4
-verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log
-Djava.awt.headless=true
-XX:+PrintGCTimeStamps -XX:+PrintGCDetails
-Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000
-XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15"

根据上面的参数我们来做一下解析:

  • -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m
    Xms,即为jvm启动时得JVM初始堆大小,Xmx为jvm的最大堆大小,xmn为新生代的大小,permsize为永久代的初始大小,MaxPermSize为永久代的最大空间。

  • -XX:SurvivorRatio=4
    SurvivorRatio为新生代空间中的Eden区和救助空间Survivor区的大小比值,默认是8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。调小这个参数将增大survivor区,让对象尽量在survitor区呆长一点,减少进入年老代的对象。去掉救助空间的想法是让大部分不能马上回收的数据尽快进入年老代,加快年老代的回收频率,减少年老代暴涨的可能性,这个是通过将-XX:SurvivorRatio 设置成比较大的值(比如65536)来做到。

  • -verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log
    将虚拟机每次垃圾回收的信息写到日志文件中,文件名由file指定,文件格式是平文件,内容和-verbose:gc输出内容相同。

  • -Djava.awt.headless=true
    Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。

  • -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
    设置gc日志的格式

  • -Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000
    指定rmi调用时gc的时间间隔

  • -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15
    采用并发gc方式,经过15次minor gc 后进入年老代

如何分析GC日志

摘录GC日志一部分

Young GC回收日志:

2016-07-05T10:43:18.093+0800: 25.395: [GC [PSYoungGen: 274931K->10738K(274944K)] 371093K->147186K(450048K), 0.0668480 secs] [Times: user=0.17 sys=0.08, real=0.07 secs]

Full GC回收日志:

2016-07-05T10:43:18.160+0800: 25.462: [Full GC [PSYoungGen: 10738K->0K(274944K)] [ParOldGen: 136447K->140379K(302592K)] 147186K->140379K(577536K) [PSPermGen: 85411K->85376K(171008K)], 0.6763541 secs] [Times: user=1.75 sys=0.02, real=0.68 secs]

通过上面日志分析得出,PSYoungGen、ParOldGen、PSPermGen属于Parallel收集器。其中PSYoungGen表示gc回收前后年轻代的内存变化;ParOldGen表示gc回收前后老年代的内存变化;PSPermGen表示gc回收前后永久区的内存变化。young gc 主要是针对年轻代进行内存回收比较频繁,耗时短;full gc 会对整个堆内存进行回城,耗时长,因此一般尽量减少full gc的次数

通过两张图非常明显看出gc日志构成:

Young GC日志:

Full GC日志:

GC分析工具

GChisto

GChisto是一款专业分析gc日志的工具,可以通过gc日志来分析:Minor GC、full gc的时间、频率等等,通过列表、报表、图表等不同的形式来反应gc的情况。虽然界面略显粗糙,但是功能还是不错的。

配置好本地的jdk环境之后,双击GChisto.jar,在弹出的输入框中点击 add 选择gc.log日志

  • GC Pause Stats:可以查看GC 的次数、GC的时间、GC的开销、最大GC时间和最小GC时间等,以及相应的柱状图

  • GC Pause Distribution:查看GC停顿的详细分布,x轴表示垃圾收集停顿时间,y轴表示是停顿次数。

  • GC Timeline:显示整个时间线上的垃圾收集

不过这款工具已经不再维护

GC Easy

这是一个web工具,在线使用非常方便.

地址: http://gceasy.io

进入官网,讲打包好的zip或者gz为后缀的压缩包上传,过一会就会拿到分析结果。

推荐使用此工具进行gc分析。

Jvm 系列(五):Java GC 分析相关推荐

  1. jvm系列(五):Java GC 分析

    Java GC就是JVM记录仪,书画了JVM各个分区的表演. 什么是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之 ...

  2. 深入JVM虚拟机(四) Java GC收集器

    转载自  深入JVM虚拟机(四) Java GC收集器 1 GC收集器 1.1 Serial串行收集器 串行收集器主要有两个特点:第一,它仅仅使用单线程进行垃圾回收:第二,它独占式的垃圾回收. 在串行 ...

  3. JVM系列之Java是解释性语言还是编译型语言?(一)

    JVM系列之Java是解释性语言还是编译型语言? 1.什么是Java语言? java语言是一门面向对象的计算机高级编程语言.编程语言(英语:programming language),是用来定义计算机 ...

  4. Jvm 系列(六):Java 服务 GC 参数调优案例

    本文介绍了一次生产环境的JVM GC相关参数的调优过程,通过参数的调整避免了GC卡顿对JAVA服务成功率的影响. 这段时间在整理jvm系列的文章,无意中发现本文,作者思路清晰通过步步分析最终解决问题. ...

  5. jvm系列(六):Java服务GC参数调优案例

    本文介绍了一次生产环境的JVM GC相关参数的调优过程,通过参数的调整避免了GC卡顿对JAVA服务成功率的影响. 这段时间在整理jvm系列的文章,无意中发现本文,作者思路清晰通过步步分析最终解决问题. ...

  6. 2021-08-20【JVM系列-2】 GC垃圾回收

    文章目录 前言 一.如何判断对象可以回收 1.1 引用计数法 1.2 可达性分析算法 1.3 四种引用 (强软弱虚) 二.垃圾回收算法 2.1 标记-清除 2.2 标记-整理 标记-复制 三.分代回收 ...

  7. JVM系列五:JVM监测工具[整理中]

    转自本站:http://www.cnblogs.com/redcreen/archive/2011/05/09/2040977.html 前几篇篇文章介绍了介绍了JVM的参数设置并给出了一些生产环境的 ...

  8. JVM系列五JVM监测工具[整理中(转)

    前几篇篇文章介绍了介绍了JVM的参数设置并给出了一些生产环境的JVM参数配置参考方案.正如之前文章中提到的JVM参数的设置需要根据应用的特性来进 行设置,每个参数的设置都需要对JVM进行长时间的监测, ...

  9. JVM必会Java GC,助你过五关斩六将

    前言 都知道<深入理解Java虚拟机>这本书对Java开发是非常重要的,几乎达到了一个必读的重要性.但是在校期间一直看不深入,就停留在最表面的意思,无法深入理解.经历了几个月的码农生活,再 ...

最新文章

  1. redis(二)redis实战 使用redis进行文章的排序
  2. win32应用程序_不是有效的win32应用程序怎么解决
  3. python_目录结构
  4. php 实现进制相互转换
  5. spring源码编译和导入eclipse
  6. java语言执行模式,使用java.exe执行静默模式
  7. 如何对您的API进行单元测试
  8. 《大型数据库技术》MySQL的进阶开发技巧
  9. python中else与if的匹配原则是什么_if-else语句中,if和else的配对原则各是什么
  10. xp系统计算机无法用搜索功能,XP系统搜索功能无法使用的六种解决方法
  11. Axure RP从入门到精通(二十)鼠标指针函数
  12. Sketch79 mac专业矢量绘图设计
  13. 编译原理——自顶向下分析中FOLLOW集的计算
  14. 饮食控制和维生素干预下肠道菌群的变化
  15. 解决:Excel 下拉项数据报 输入内容不能大于255个字符
  16. 费用报销与对公付款电子化管理系统:iBox+RPA已形成自动化闭环
  17. 阿里云esc服务器上装hadoop
  18. JavaScript实现输入数值判断是否为质数、合数的代码
  19. Day 09 (JAVA中的queryWrapper)
  20. el表达式ne什么意思_el表达式中的比较eq ne gt lt

热门文章

  1. Nature综述 | 种内多样性:解释微生物组中的菌株
  2. 张和平:益生菌、肠道菌群与健康 |《科学通报》专辑
  3. linux中sed深入,Linux中的sed
  4. java 传入参数_java参数怎么传递参数
  5. 修改串口设备名ttymxc1_Modbus通讯之串口联网设备
  6. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、设置transpose参数转置三线表、变量作为列,子组(strata)作为行
  7. R语言可视化分别使用lattice包和ggplot2包可视化热图(heatmap)并绘制热力图对应的系统树图(dendrogram)实战
  8. pandas计算dataframe数据行的均值(mean)实战:设置skipna=False则计算行均值时不会忽略NaN值
  9. Python中matplotlib默认绘制的条形图比较胖?如何设置成体型匀称的条形图,达到最佳的可视化效果。
  10. 异常检测算( OneClassSVM、EllipticEnvelope、IsolationForest、LocalOutlierFactor)法比较,基于四个仿真数据集