在JVM中只有一个堆内存,堆的内存大小可以调节。

类加载器读取类文件后,一般会把类、方法、常亮、变量、保存引用的实例对象放到堆中。

堆内存分为三个区域:

  • 新生区(伊甸园区、幸存0区、幸存1区)
  • 养老区
  • 永久区(1.8后为元空间)

在新生区中,对象经过轻GC在伊甸园区、幸存者0、1区过渡,后经过重GC(Full GC)过渡到养老区。GC垃圾回收,主要是在伊甸园区和养老区。新生区和养老区都满了会报OOM错误。 

 新生区

  • 类:诞生和成长、死亡;
  • 伊甸园区:所有的类都是在伊甸园区new出来的;
  • 幸存者0、1区

永久区

这个区域是常驻内存的,用来存放JDK自身携带的Class对象。Interface元数据,存储的是Java运行时的一些环境或类信息,这个区域不存在垃圾回收。关闭VM虚拟就会释放这个区域的内存。

元空间逻辑上存在,物理上不存在,也称作非堆。理论上,JVM最大内存(-Xmx)为计算机内存的1/4,初始化内存(-Xms)为计算机内存的1/64。

遇到OOM可以:

  • 调整JVM内存:-Xms104m -Xmx1024m -XX:+PrintGCDetails
  • 分析内存,看一下那个地方出现问题(MAT、JProfiler)

MAT、JProfiler作用:

  • 分析Dump内存文件,快速定位内存泄漏;-XX:HeapDumpOnOutOfMemoryError
  • 获得堆中的数据;
  • 获得大的对象;
  • ....
原文地址:https://www.cnblogs.com/zqzhen/p/12668236.html