用户登录
用户注册

分享至

JVM运行时数据5个区域-堆(Heap)

  • 作者: 淘店铺-牛仔部落1947
  • 来源: 51数据库
  • 2021-08-21

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]);
}

如下会报堆空间溢出异常:

软件
前端设计
程序设计
Java相关