文章目录

  • 一、前言
  • 二、示例讲解
  • 三、拓展阅读



一、前言

在前期博文中,我们只设置了整个堆的内存大小。但是我们知道,堆又分为了新生代年老代。他们之间的内存怎么分配呢?新生代又分为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文件中。运行后得到以下日志,这是第一部分:

java项目linux部署一直打印debug的日志怎么关_Test


现在我们来分析下每个部分代表的含义:

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

我们再来看看第二部分:

java项目linux部署一直打印debug的日志怎么关_内存_02


看图画红线部分,表示当前的堆中新生代可用内存的大小(一个eden和一个Survivor视为可用内存),红色框下面则是年老区的大小,加上一共是20m,符合我们所设置的。红色框中的部分则是新生代中eden区和两个Survivor区的大小,可以看出他们的比例是8:1,如果设置为-XX:SurvivorRatio=3的话,结果如下

java项目linux部署一直打印debug的日志怎么关_Test_03


到这里以上几个参数的作用以及分析就讲完啦,小伙伴们可以打开自己的工具试一试,感受一下。以后碰到了内存泄漏或者内存不足的话就可以直接查看日志来进行分析调优了!

三、拓展阅读

  • 《JVM虚拟机专栏》