JVM简笔—堆(Heap)内存的基本结构

堆(Heap)

  • Java堆内存是影响性能的主要因素,是线程共享的一块内存区域
  • 一般用来存放对象和数组,所有的对象实例都需要在堆中进行分配

堆内存的划分

堆内存溢出是非常常见的问题,解决问题之前,了解堆内存基本结构是很有必要的

JVM堆内存图
在这里插入图片描述

  • JVM内存分为堆内存和非堆内存(永久代)
  • 堆内存分为新生代和老年代

新生代

  • 默认约占1/3的堆内存
  • JVM创建新对象的地方(大对象除外)
  • 对象的创建和销毁最频繁的区域
  • 垃圾回收的主要区域
  • 特点:朝生夕死

新生代又分为Eden区(伊甸园区)和Survivor区(幸存者区)!

新生代对象的生命周期是由MinorGC决定的,先了解MinorGC的原理–复制算法(MinorGC三步:)

在这里插入图片描述

  1. 将Eden存活下来的和SurvivorFrom中的对象复制到To区,同时将这些对象的年龄加一,如果这些对象中已经存在达到老年代标准的对象或者To区的内存不足,就会将这些对象放到老年代
  2. 清空Eden和From区中的这些对象
  3. From与To相互交换,原来To区成为下一次MinorGC的From区,所以在一段时间内SurvivorFrom区和SurvivorTo区总有一个为空

老年代

  • 存放有长生命周期的对象(指新生代中经过多次MinorGC达到老年代标准的对象)和 大对象
  • 垃圾回收为MajorGC
  • 对象比较稳定,不会频繁的触发垃圾回收
  • 老年代内存空间不足时,会抛出OOM

在这里插入图片描述

永久代

  • 指内存的永久储存区域
  • 存储程序运行时长期存活的对象,比如类、方法、常量、属性等元数据
  • GC不会再程序运行期间对永久代进行清理
  • 永久代的内存会随着元数据加载的增加而增加,当超出内存时会遇到OOM错误(这种情况很少,因此不是内存设置的主要区域)

扩展

设置Survivor(幸存者)区的意义?

减少进入老年代的对象,如果不设置幸存者区,那么每一次MinorGC存活的对象都会进入老年代,当老年代内存满了之后会进行MajorGC,会大大的影响程序的性能

为什么要设置两个Survivor(幸存者)区?

防止内存碎片化。

上面我们了解了MinorGC的原理----将Eden和SurvivorFrom中存活下来的对象复制到SurvivorTo区,From区和To区交换;所以每一次存活的对象都会进入一个空的To区,然后依次分配,就保证了分配的内存是连续的,也就不会出现内存碎片化。

如果仅仅设置一个,那么每次MinorGC过后存活的对象进入Survivor区,都会有已经保存在其中的对象,就出现了内存不连续的情况,导致内存碎片化

SurvivorFrom和SurvivorTo区内存大小必须严格相等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值