JVM之堆区

本文详细介绍了Java虚拟机(JVM)堆内存的结构,包括新生代、老年代和元空间,并讲解了如何设置堆内存大小。同时,讨论了堆区可能导致的两种OutofMemoryError情况及对象分配过程,包括 MinorGC 和 MajorGC 的作用。此外,还概述了对象内存分配策略,如优先分配到伊甸园区、大对象直接入老年代等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2.4堆

一个JVM实例中只存在一个堆区,堆也是Java内存管理的核心区域。

堆区的唯一目的就是存放对象实例,几乎所有的对象实例以及数据都在这里进行分配内存。

Java堆是垃圾收集器管理的主要区域,因此也被称为GC堆。

(1)堆的内存划分

  • 新生代
    • Eden
    • Survivor
      • from
      • to
  • 老年代
  • 元空间(永久代)

(2)设置堆内存大小

  • -Xmx 用来表示堆的起始内存 , 默认情况下,初始堆内存大小为: 电脑内存大小 / 64
  • -Xms 用来表示堆的最大内存 , 默认情况下,最大堆内存大小为: 电脑内存大小 / 4

(3)堆区常见的OOM

  • java.lang.OutOfMemoryError: GC Overhead Limit Exceeded : 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误。
  • java.lang.OutOfMemoryError: Java heap space :假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发此错误。
  • Permgen space:永久代已满,通常是加载的class数目太多或者是体积太大、

对象分配过程

  • new 的对象先存放在eden区,但是伊甸园区有大小限制
  • 当eden空间填满时,程序有需要创建对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁,再加载新的对象放到伊甸园区
  • 然后将伊甸园中的剩余对象移动到幸存者0区
  • 如果再次触发垃圾回收,此时上次幸存下来的放到幸存者0区,如果没有i回收,就会放到幸存者1区
  • 默认是15次回收标记就会进入老年代
  • 在老年代内存不足时,再次触发Major GC,进行老年代的内存清理
  • 如果老年代执行了Major GC之后发现依然无法进行对象保存,就会产生OOM异常

内存分配策略

  • 优先分配到伊甸园区
  • 大对象直接分配到老年代
  • 长期存活的对象分配到老年代
  • 如果survivor区中相同年龄的所有对象大小总和大于survivor空间的一半,年龄大于或者等于该年龄的对象可以直接进入老年代
  • 空间分配担保
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值