java垃圾回收过程

垃圾回收的日志没有在这里截图了,大家可以使用-verbose:gc 参数,在控制台输出你的程序的 GC 情况或同时输出至 log 文本文件中(-Xloggc: 日志文件路径)。 对控制台输出或 log 文件进行简要分析。

 

首先从jstat -gc打印出的结果,我们可以清楚的看到年轻代分区的情况

1. 新生代内存按照8:1:1的比例分为一个eden区和S0、S1区。大部分对象在Eden区中生成,回收时先将eden区存活对象复制到一个S0区,然后清空eden区。

2. 当这个S0区也存放满了时,则将eden区和S0区存活对象复制到另一个S1区,然后清空eden和这个S1区,此时S0区是空的,然后将S0区和s1区交换,即保持S1区为空,如此往复。

3. 这里也解释了为什么命令行jstat -gc每个2500ms打印结果的时候,S0和S1的大小交替变换。

 

然后再从日志分析结果,当我-XX:NewSize=500m:设置年轻代初始值为500M时。发现gc时大部分的的在年轻代会被回收,大约只有有20M大小的对象会进入老年代。

1. 一方面根据我程序实现时,对象的存活周期大多较短,另一方面,所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。

2. 当survivor1区不足以存放 eden和S0的存活对象时,就将存活对象直接存放到老年代。若是老年代也满了就会触发一次Full GC,也就是新生代、老年代都进行回收

3. 新生代发生的GC也叫做Minor GC,MinorGC发生频率比较高(不一定等Eden区满了才触发)

 

我们再结合着jmap -heap打印出的结果来分析,以下主要讨论年老代和Metaspace。

1. 在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。

2.当老年代内存满时触发Full GC,Full GC发生频率比较低,老年代对象存活时间比较长,存活率标记高。

3. Metaspace用于存放静态文件,如Java类、方法等。结合着日志,我们会发现Metaspace的大小变化总是不大,事实上Metaspace对垃圾回收没有显著影响。Metaspace包含JVM用于描述应用程序中类和方法的元数据,是由JVM在运行时根据应用程序使用的类来填充的。

你可能感兴趣的:(软件构造,Java)