【JVM 堆 03】

朝九晚五浪迹江湖 / 2023-05-06 / 原文

一、堆的细分内存结构

1、Java 8 及之后堆内存逻辑上分为三部分:新生区+养老区+元空间

Young Generation Space    新生区     Young/New

  又被划分为Eden区和Survivor区

Tenure Generation space    养老区    Old/Tenure

Meta  Space          元空间    Meta

#案例演示:程序运行时堆的空间结构

1、编写代码

public class StarckFrameTest {
    private int id;
    public StarckFrameTest(int id){
        this.id = id;
    }
    public void show(){
        System.out.println("My ID is "+id);
    }
    public static void main(String[] args) {
        StarckFrameTest s1 = new StarckFrameTest(1);
        StarckFrameTest s2 = new StarckFrameTest(2);

        int[] arr = new int[10];
        Object[] arr1 = new Object[10];
    }
}

在run-Edit Configuration中设置-Xms10m -Xmx10m -XX:+PrintGCDetails (-Xms10m -Xmx10m设置堆大小,-XX:+PrintGCDetails设置打印的堆信息)

设置后执行程序,输出结果:

Heap
 PSYoungGen      total 2560K, used 1461K [0x00000007bfd00000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 2048K, 71% used [0x00000007bfd00000,0x00000007bfe6d578,0x00000007bff00000)
  from space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
  to   space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)
 ParOldGen       total 7168K, used 0K [0x00000007bf600000, 0x00000007bfd00000, 0x00000007bfd00000)
  object space 7168K, 0% used [0x00000007bf600000,0x00000007bf600000,0x00000007bfd00000)
 Metaspace       used 3067K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 340K, capacity 388K, committed 512K, reserved 1048576K

二、堆空间大小的设置和查看

1、Java堆区用于存储Java对象实例,那么堆的大小在JVM启动时就已经设定好了,可通过-Xms和-Xms来进行设置

  • -Xms表示堆区的起始内存
  • -Xmx表示堆区的最大内存 (用来设置堆空间(年轻代+老年代)的最大内存大小)

2、一旦堆区中的内存大小超过-Xmx所指定的最大内存时,将会抛出OOM异常

3、通常会将-Xms和-Xmx两个参数配置相同的值,其目的是为了能够在Java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小,从而提高性能

4、默认情况下,初始内存大小=物理电脑内存大小的 / 64

      最大内存大小=物理电脑内存大小的 / 4

5、查看设置的参数:

  • 方法1:jps查看进程ID ->jstat -gc 进程ID查看新生代,老年代的参数
  • 方法2: -XX:+PrintGCDetails (idea中run-Edit Configuration中设置)

三、新生代与老年代中相关参数的设置