JVM Series (3): Heap (Heap)

Introduction


Java heap (Java Heap) is the largest piece of memory in the Java virtual machine management. Java heap is shared by all threads in a memory area is created when the virtual machine starts. The sole purpose of this memory area is stored object instance, almost all object instances are here to allocate memory. Java heap is the main area managed by the garbage collector, and therefore often also called "GC heap." If you look from the perspective of memory recovery, due to the current collector basically adopted generational collection algorithm, so the Java heap can also be broken down into: the old and the new generation's; and then there is little detailed Eden space, From Survivor space, To Survivor space. Under the Java Virtual Machine specification, Java heap may be in discontinuous physical memory space, as long as logically contiguous to, just like our disk space. When implemented, may be implemented as a fixed size, it can be expanded, but the current mainstream is an extensible virtual machine implemented (by -Xms -Xmx and control). If there is no complete examples in the heap memory allocation, and the stack can no longer expand, it will throw an OutOfMemoryError.

 

Heap composition


  A. Young Generation Space: the young generation Young / New

  Two .Tenure generation space: Pension Area Old / Tenure

  Three .Permanent Space: Permanent Perm region

  There is only one instance of a JVM memory heap, the memory heap size can be adjusted. After the class loader reads the class files need to classes, methods, variables often into the heap memory, hold true for all reference types of information to facilitate Actuators

  Stack may be logically divided into three parts: the young generation, pension area, permanent area (called 1.8-dimensional space)

  Physically divided into: the New Area, Area Aged

  

Freshmen District Young / New


 Freshman class district is born, growing, dying area, where a class is generated, application, and finally collected the garbage collector, the end of life. Freshmen area is divided into two parts:

  伊甸区(Eden space):所有的类都是在伊甸区被 new 出来的。
  幸存者区(Survivor pace):幸存区有两个: 0 区(Survivor 0 space)和 1 区(Survivor 1 space),又叫from 和 to
  当伊甸园的空间用完时,程序又需要创建对象,JVM 的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC,轻GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。然后将伊甸园中的剩余对象移动到幸存 0区。若幸存 0 区也满了,再对该区进行垃圾回收,然后移动到 1区。那如果 1 区也满了呢?再移动到养老区

 

养老区  Old/ Tenure


 当对象在新生区经历过多次(默认 15 次)GC 依然幸存则进入养老区。若养老区也满了,那么这个时候将产生MajorGC(FullGC,重GC),进行养老区的内存清理。若养老区执行了 Full GC 之后发现依然无法进行对象的保存,就会产生OOM 异常“OutOfMemoryError”

如果出现 java.lang.OutOfMemoryError: Java heap space 异常,说明 Java 虚拟机的堆内存不够。

原因有二:
  (1)Java 虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx 来调整。
  (2)代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)。

 

永久区  Perm 


 

永久存储区是一个常驻内存区域,用于存放 JDK 自身所携带的 Class,Interface 的元数据,也就是说它存储的是运行环境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭 JVM 才会释放此区域所占用的内存。如果出现 java.lang.OutOfMemoryError: PermGen space,说明是 Java 虚拟机对永久代 Perm 内存设置不够。一般出现这种情况,都是程序启动需要加载大量的第三方 jar 包。

  例如:在一Tomcat 下部署了太多的应用。或者大量动态反射生成的类不断被加载,最终导致 Perm 区被占满。

Jdk1.6 及之前: 有永久代, 常量池 1.6 在方法区

Jdk1.7:有永久代,但已经逐步“去永久代”,常量池 1.7 在堆

Jdk1.8 及之后: 无永久代,常量池 1.8 在元空间

  实际而言,方法区(Method Area)和堆一样,是各个线程共享的内存区域,它用于存储虚拟机加载的:类信息+普通常量+静态常量+编译器编译后的代码等等,虽然 JVM 规范将方法区描述为堆的一个逻辑部分,但它却还有一个别名叫做 Non-Heap(非堆),目的就是要和堆分开。

  对于 HotSpot 虚拟机,很多开发者习惯将方法区称之为“永久代(Parmanent Gen)” ,但严格本质上说两者不同,或者说使用永久代来实现方法区而已,永久代是方法区(相当于是一个接口 interface)的一个实现,jdk1.7 的版本中,已经将原本放在永久代的字符串常量池移走。常量池(Constant Pool)是方法区的一部分,Class 文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池,这部分内容将在类加载后进入方法区的运行时常量池中存放。

Guess you like

Origin www.cnblogs.com/steakliu/p/12113164.html