Java 堆的结构是什么样子的?
Posted 四猿外
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 堆的结构是什么样子的?相关的知识,希望对你有一定的参考价值。
JVM 的堆是运行时数据区,所有类的实例和数组都是在堆上分配内存。它在JVM 启动的时候被创建。对象所占的堆内存是由自动内存管理系统也就是垃圾收集器回收。
堆内存是由存活和死亡的对象组成的。存活的对象是应用可以访问的,不会被垃圾回收。死亡的对象是应用不可访问尚且还没有被垃圾收集器回收掉的对象。一直到垃圾收集器把这些对象回收掉之前,他们会一直占据堆内存空间。
永久代是用于存放静态文件,如Java 类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类,永久代中一般包含:
-
类的方法(字节码…)
-
类名(Sring 对象)
-
.class 文件读到的常量信息
-
class 对象相关的对象列表和类型列表(e.g., 方法对象的array).
-
JVM 创建的内部对象
-
JIT 编译器优化用的信息
虚拟机中的共划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和持久代(Permanent Generation)。
其中持久代主要存放的是Java 类的类信息,与垃圾收集要收集的Java 对象关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的。
年轻代:
所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生
命周期短的对象。年轻代分三个区。一个Eden 区,两个Survivor 区(一般而言)。大部分对
象在Eden 区中生成。当Eden 区满时,还存活的对象将被复制到Survivor 区(两个中的一个),
当这个Survivor 区满时,此区的存活对象将被复制到另外一个Survivor 区,当这个Survivor
去也满了的时候,从第一个Survivor 区复制过来的并且此时还存活的对象,将被复制“年老
区(Tenured)”。需要注意,Survivor 的两个区是对称的,没先后关系,所以同一个区中可能同
时存在从Eden 复制过来对象,和从前一个Survivor 复制过来的对象,而复制到年老区的只
有从第一个Survivor 去过来的对象。而且,Survivor 区总有一个是空的。同时,根据程序需
要,Survivor 区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时
间,减少被放到年老代的可能。
年老代:
在年轻代中经历了N 次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认
为年老代中存放的都是一些生命周期较长的对象。
持久代:
用于存放静态文件,如今Java 类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。
注意:JDK1.8 中,永久代已经从
以上是关于Java 堆的结构是什么样子的?的主要内容,如果未能解决你的问题,请参考以下文章
别再写一堆的 for 循环了!Java 8 中的 Stream 轻松遍历树形结构,是真的牛逼!