一文读懂从 GC 日志分析堆内存

举报
SHQ5785 发表于 2022/04/14 09:33:49 2022/04/14
【摘要】 一、前言在前期博文中,我们只设置了整个堆的内存大小。但是我们知道,堆又分为了新生代,年老代。他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比例大小能改变吗?其实这些都是可控的,以前没有讲到是因为就算讲了也只是讲讲而已,看不到实质性的东西。因此,这篇博文我们通过分析GC日志来一步步讲解如何细化设置堆内存。首先我们来了解几个相关的参数:-XX:+PrintGCDeta...

一、前言

在前期博文中,我们只设置了整个堆的内存大小。但是我们知道,堆又分为了新生代年老代。他们之间的内存怎么分配呢?新生代又分为EdenSurvivor,他们的比例大小能改变吗?其实这些都是可控的,以前没有讲到是因为就算讲了也只是讲讲而已,看不到实质性的东西。因此,这篇博文我们通过分析GC日志来一步步讲解如何细化设置堆内存。

首先我们来了解几个相关的参数:

  • -XX:+PrintGCDetails:用于告诉虚拟机回收垃圾的时候顺便打印日志;
  • -Xloggc:路径 :将打印出来的日志信息保存至指定的路径;
  • -Xmn10M:设置新生代的内存大小;
  • -XX:SurvivorRatio=8:1:调整EdenSurvivor的比例为8:1;

二、示例讲解

我们还是用前面的代码例子来讲:

public class Test {
	private static List<Test> list = new ArrayList<Tets>();
	public static void main(String[] args){
		while (true) {
			Test test = new Test();
			list.add(test);
		}
	}
}

然后用参数-Xms20m -Xmx20m -Xmn10
-XX:+PrintGCDetails -Xloggc:d:\gc1.log启动。表示给堆分配20M,给新生代分配10M,并打印GC日志,并将其输出至D盘的gc1.log文件中。运行后得到以下日志,这是第一部分:
这里写图片描述
现在我们来分析下每个部分代表的含义:

  • 0.090:就是虚拟机从启动到现在经历的时间(单位:s)。
  • GC:指的是停顿类型(留着下一章讲)
  • PSYoungGen:发生GC的区域,这里指的是年轻代。根据收集器的种类而定。
  • 7284K->1016K(9216K):该区域GC前当前区域所使用的容量–>该区域GC后已使用的容量(该区域的总容量),也就是新生代的容量。
  • 7284K->6139K(19456K):整个堆GC前当前区域所使用的容量–>整个堆GC后已使用的容量(整个堆的总容量)。
  • 0.0078481:这次GC所占用的时间(单位:s)。

我们再来看看第二部分:
这里写图片描述
看图画红线部分,表示当前的堆中新生代可用内存的大小(一个eden和一个Survivor视为可用内存),红色框下面则是年老区的大小,加上一共是20m,符合我们所设置的。

红色框中的部分则是新生代中eden区和两个Survivor区的大小,可以看出他们的比例是8:1,如果设置为-XX:SurvivorRatio=3的话,结果如下
这里写图片描述
到这里以上几个参数的作用以及分析就讲完啦,小伙伴们可以打开自己的工具试一试,感受一下。以后碰到了内存泄漏或者内存不足的话就可以直接查看日志来进行分析调优了!

三、拓展阅读

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。