jvm中的堆

本文详细解读堆的内存分配原理,包括eden区、to/survivor区、老年代以及新生代与老年代的划分。重点介绍垃圾回收机制,如引用计数和可达性分析,并探讨了TLAB、minor GC和major GC的过程。

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

  • 堆主要的作用是给对象分配空间并且存放对象的实例,同时堆是垃圾回收的主要区域,又被称为gc堆
  • 从垃圾回收的角度,堆被分为新生代(minor gc或者younggc)和老年代(major gc或者full gc)
  • 从内存分配的角度看,eden将会划分出一小块空间,用作本地线程分配缓冲区(tlab),每个线程都有自己的tlab,当对象比较小时,直接可以使用tlab给对象分配内存,如果tlab不够,考虑用eden分配,eden不够则直接进入老年代

堆的结构

堆分区主要是因为大多数对象存活的时间短,优化gc的能力

  • eden区(新生代):里面又分为 from survivor 和 to survivor,默认比例是8:1:1
  • 老年代:新生代与老年代的比例是1:2
  • 永久代: 永久代指的是方法区

1.8后去除掉了永久代的概念,也就是方法区,使用元空间(直接内存)

堆的内存分配过程

  • 最开始应该使用线程分配缓冲区(tlab)来给对象分配空间,每个线程都有一个tlab,它可以保证线程的安全
  • 使用tlab分配空间失败时考虑通过加锁的方式(多线程),在eden区分配空间,如果eden区满了,就会触发一次minor gc,它会清除掉没有用的对象,判断一个对象是否能被搜集通常有两种算法:引用计数器法、可达性分析法;存活下来的对象将会进入eden的from区,然后清空eden区
  • 当eden区,会第二次触发minor gc,他会将eden存活下来的对象放入to区,from存活下来的对象年龄+1后也进入to区,然后清空eden区和from区
  • 当eden区再次满时,第三次执行minor gc,这一次eden区存活下来的对象进入from区,to区存活下来的对象年龄+1也会进入from区,然后清空eden区和to区
  • 随着对象的数量增加,不停的做上面两次操作,到对象的年龄到达老年带所规定的年龄阈值的时候,对象从新生代进入老年代
  • 随着对象增加,老年代满时会执行major gc操作,gc后对象仍然无法保存报内存溢出

System.gc()会触发major gc执行
老年代满时会触发major gc执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值