代码演示GC回收

133次阅读
没有评论

共计 1516 个字符,预计需要花费 4 分钟才能阅读完成。

 

JVM配置

-XX:NewSize=5m 初始新生代大小
-XX:MaxNewSize=5m 最大新生代大小
-XX:InitialHeapSize=10m 初始堆大小 等同于Xms
-XX:MaxHeapSize=10m 最大堆大小 等同于Xmx
-XX:SurvivorRatio=8 Eden区占80%
-XX:PretenureSizeThreshold=10m 大对象阈值
-XX:+UseParNewGC 新生代使用ParNew
-XX:+UseConcMarkSweepGC 老年代使用CMS
-XX:+PrintGCDetils:打印详细的gc日志
-XX:+PrintGCTimeStamps:这个参数可以打印出来每次GC发生的时间
-Xloggc:gc.log:这个参数可以设置将gc日志写入一个磁盘文件

代码

public class ParNew {
public static void main(String[] args) {
System.out.println("main方法压入栈帧-----");
int size = 1024 * 1024;
System.out.println("在main的栈帧内创建一个arrarray11变量,并在eden区开辟一块1m的内存,变量arr1指向这块你内存");
byte[] array1 = new byte[size];
System.out.println("在堆内存的Eden区中创建第二个数组,并且让局部变量指向第二个数组,第一个数组就没人引用了,此时第一个数组就成了没人引用的“垃圾对象”");
array1 = new byte[size];
System.out.println("在堆内存的Eden区内创建了第三个数组,同时让array1变量指向了第三个数组,此时前面两个数组都没有人引用了,就都成了垃圾对象");
array1 = new byte[size];
System.out.println("array1这个变量什么都不指向了,此时会导致之前创建的3个数组全部变成垃圾对象");
array1 = null;
System.out.println("此时会分配一个2MB大小的数组,尝试放入Eden区中,但是Edeb区只剩1m了,所以会触发Minor GC");
byte[] arr2 = new byte[2 * size];
}
}

代码分析

  1. byte[] arr1 = new byte[size];这行代码一旦运行,就会在JVM的Eden区内放入一个1MB的对象,同时在main线程的虚拟机栈中会压入一个main()方法的栈帧,在main()方法的栈帧内部,会有一个“array1”变量,这个变量是指向堆内存Eden区的那个1MB的数组,如下图。

代码演示GC回收

  1. array1 = new byte[size];此时会在堆内存的Eden区中创建第二个数组,并且让局部变量指向第二个数组,然后第一个数组就没人引用了,此时第一个数组就成了没人引用的“垃圾对象”了,如下图所示。代码演示GC回收
  2. array1 = new byte[size];这行代码在堆内存的Eden区内创建了第三个数组,同时让array1变量指向了第三个数组,此时前面两个数组都没有人引用了,就都成了垃圾对象,如下图所示。代码演示GC回收
  3. array1 = null;这行代码一执行,就让array1这个变量什么都不指向了,此时会导致之前创建的3个数组全部变成垃圾对象,如下图。代码演示GC回收
  4. byte[] arr2 = new byte[2 * size];此时会分配一个2MB大小的数组,尝试放入Eden区中,因为Eden区总共就4MB大小,而且里面已经放入了3个1MB的数组了,所以剩余空间只有1MB了,此时你放一个2MB的数组是放不下的,所以这个时候就会触发年轻代的Young GC。

正文完
 
yangleduo
版权声明:本站原创文章,由 yangleduo 2023-04-07发表,共计1516字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。