JVM运行时数据5个区域-堆(Heap)
程序员文章站
2022-06-28 08:00:01
JVM运行时的数据区域运行时的数据区分为私有线程和共享线程两个区域u,其中堆Heap属于共享线程。描述:存放对象实例,如对象(new Person())、数组(new Person[2])。堆是jvm区域中最大的一块(对象会在多个地方进行创建),在jvm启动时就已经创建完毕(堆容器)。堆本身是线程共享,但在堆内部可以划分出多个线程的私有缓冲区。GC主要管理的区域。堆允许物理空间不连续,只要逻辑连续即可(对象会在堆中到处存放,但是都属于同一类对象)。堆的详细图解如下:新生代和老生代:...
JVM运行时的数据区域
运行时的数据区分为私有线程和共享线程两个区域,其中堆Heap属于共享线程。
描述:
- 存放对象实例,如对象(new Person())、数组(new Person[2])。
- 堆是jvm区域中最大的一块(对象会在多个地方进行创建),在jvm启动时就已经创建完毕(堆容器)。
- 堆本身是线程共享,但在堆内部可以划分出多个线程的私有缓冲区。
- GC主要管理的区域。
- 堆允许物理空间不连续,只要逻辑连续即可(对象会在堆中到处存放,但是都属于同一类对象)。
堆的详细图解如下:
新生代和老生代:
- 堆可以划分为新生代、老生代,比例 为新生代:老生代 = 1 :3。
- 新生代中包含Eden、S0(From Survivor)、S1(To Survivor),比例 Eden :S0 :S1 = 8 :1 :1。
- 新生代的使用率一般在90%。在使用时只能使用一个Sden区和一块S区(S0和S1)。
- 新生代在使用时只能使用其中的一个S区(S0、S1)。
- 新生代:
- 存放生命周期比较短的对象。
- 存放较小的对象。
- 对象的大小可以通过参数设置 -XX: PretnureSizeThredshold = 16(默认是16),小于16进入新生代,否则进入老生代。大对象一般是集合、数组、字符串。对象的生命周期可以通过参数设置 -XX: MaxTenuringThredshold = 100ms。
- 新生代老生代年龄:
- MinorGC回收新生代中的对象(复制算法,防止碎片产生)。
- 若Eden区中的对象经历过一次回收仍然存活,就会被转移到S区中。
- 转入S区后继续被垃圾回收仍然存活,则年龄 +1。
- 当年龄增长到一定的数字,则会被转入老生代中。
- 老生代:
- 存放生命周期比较长的对象(一般从新生代转过来)。
- 存放较大的对象(有些对象较大,不经过新生代,直接到老生代)。
- 老生代主要使用垃圾回收器是Major GC/Full GC(标记清除算法),该GC是对整个堆空间进行垃圾回收,当内存空间不足时会触发一次垃圾回收:
- 先将对象进行标记。
- 再通过循环遍历清除堆中未被标记的对象。
新生代老生代特点:
- 新生代:大部分对象在新生代,回收频率高、效率高。
- 老生代:空间大、增长速度慢、频率低。
意义:
- 可以根据项目中对象大小的数量,设置新生代或老生代的空间容量,从而提高GC性能。
虚拟机参数:
- -Xms128m: JVM启动时大小。
- -Xmn32m: 新生代大小。
- -Xmx128m: 总大小,一般与启动大小相等。
- JVM总大小 = 新生代 + 老生代。
堆溢出异常实例:
List list = new ArrayList();
while (true) {
list.add(new int[1024 * 1024]);
}
如下会报堆空间溢出异常:
本文地址:https://blog.csdn.net/Yh_yh_new_Yh/article/details/112004257