JVM深入理解 (3)

JVM深入理解

堆结构详解

新生区

类诞生、生长、以及可能死亡的地方

伊甸园:所有对象的实例化都是在伊甸园产生的

幸存区:伊甸园中经过垃圾回收后还存活的对象会进入到幸存区

老年区

新生区中经过垃圾回收后还存活的对象会进入到老年区

永久区

存储的是Java运行时的一些环境或类信息,JVM被关闭后会释放这个区域的内存,不存在垃圾回收

永久区是逻辑上存在但是物理上不存在的一片区域

jdk 1.6 之前:名为永久代,此时常量池在方法区中

jdk 1.7:名为永久代,但永久代慢慢退化,此时常量池在堆中

jdk 1.8 之后:名为元空间,此时常量池在元空间中

//查看堆内存具体各区域所占空间大小,本例中虚拟机的总内存为2M

//查看虚拟机的总内存,代码如下
long totalMemory = Runtime.getRuntime().totalMemory();
//输出结果:虚拟机的总内存为:2.0MB
System.out.println("虚拟机的总内存为:" + (totalMemory/(double)1024/1024) + "MB");

//打印GC详细信息
Heap
PSYoungGen    total 1536K,
    used 1455K [0x00000000ffd80000, 0x00000000fff80000, 0x0000000100000000)
    eden space 1024K,
        94% used [0x00000000ffd80000,0x00000000ffe71e10,0x00000000ffe80000)
    from space 512K,
        95% used [0x00000000fff00000,0x00000000fff7a020,0x00000000fff80000)
    to   space 512K
        0% used [0x00000000ffe80000,0x00000000ffe80000,0x00000000fff00000)
ParOldGen    total 512K,
    used 128K [0x00000000ff800000, 0x00000000ff880000, 0x00000000ffd80000)
    object space 512K,
        25% used [0x00000000ff800000,0x00000000ff820000,0x00000000ff880000)
Metaspace    used 3505K, capacity 4500K, committed 4864K, reserved 1056768K
 class space    used 389K, capacity 392K, committed 512K, reserved 1048576K
             
//结果分析
PSYoungGen(新生代):共1536k,1.5MB
ParOldGen(老年代):共512k,0.5MB
这些相加总内存已经等于2MB了,所以即使永久区(元空间)使用的有内存,但是它逻辑上存在但是物理上不存在

  8.2、OOM

OutOfMemoryError:内存不足错误,说明堆内存满了

解决:

使用堆内存调优参数调整堆内存大小,排查是否还会出错

若还会出错,使用JProfiler工具分析内存,排查具体出错位置

  8.3、堆内存调优参数

-Xms1m:

设置初始化内存分配大小,默认为内存大小的1/64

-Xmx8m:

设置最大分配内存,默认为内存大小的1/4

-XX:+PrintGCDetails:

打印垃圾回收的详细信息

-XX:+HeapDumpOnOutOfMemoryError

Dump内存文件

-XX:MaxTenuringThreshold(默认15):

设置幸存区里的对象经过多少次GC会进入老年区

......

  8.4、使用JProfiler工具分析OOM

首先要设置Dump内存文件

配置:-XX:+HeapDumpOnOutOfMemoryError

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgxgw.html