垃圾回收算法(7)-分代回收算法

本文深入解析Java堆内存的结构,包括年轻代与老年代的划分,Eden区及Survivor区的作用,以及垃圾回收机制(MinorGC与FullGC)的工作原理。详细介绍了堆内存的配置参数,帮助理解Java内存管理。

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

前言

Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。
在 Java 中,堆被划分成两个不同的区域:年轻代 ( Young )、老年代 ( Tenured)。年轻代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。 这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。

堆大小 = 年轻代 + 老年代
年轻代 = eden space (新生代) + from survivor + to survivor
Java 中的堆也是 GC 收集垃圾的主要区域。GC 分为两种:Minor GC、Full GC ( 或称为 Major GC )

图片.png

新生代

Eden 是内存中的一个区域, 用来分配新创建的对象。通常会有多个线程同时创建多个对象, 所以 Eden 区被划分为多个 线程本地分配缓冲区(Thread Local Allocation Buffer, 简称TLAB)。通过这种缓冲区划分,大部分对象直接由JVM 在对应线程的TLAB中分配, 避免与其他线程的同步操作。

如果 TLAB 中没有足够的内存空间, 就会在共享Eden区(shared Eden space)之中分配。如果共享Eden区也没有足够的空间, 就会触发一次 年轻代GC 来释放内存空间。如果GC之后 Eden 区依然没有足够的空闲内存区域, 则对象就会被分配到老年代空间(Old Generation)。

年轻代的特点是产生大量的死亡对象,并且要是产生连续可用的空间, 所以使用复制清除算法和并行收集器进行垃圾回收.对年轻代的垃圾回收称作初级回收 (minor gc)。

初级回收将年轻代分为三个区域, 一个新生代 , 2个大小相同的复活代, 应用程序只能使用一个新生代和一个复活代, 当发生初级垃圾回收的时候,gc挂起程序, 然后将新生代和复活代中的存活对象复制到另外一个非活动的复活代中,然后一次性清除新生代和复活代,将原来的非复活代标记成为活动复活代.将在指定次数回收后仍然存在的对象移动到老年代中, 初级回收后,得到一个空的可用的新生代.。

Minor GC 是发生在新生代中的垃圾收集动作,所采用的是复制算法。

老年代

当一个对象被判定为 “死亡” 的时候,GC 就有责任来回收掉这部分对象的内存空间。新生代是 GC 收集垃圾的频繁区域。 当对象在 Eden 出生后,在经过一次 Minor GC 后,如果对象还存活,并且能够被另外一块 Survivor 区域所容纳,则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域中,然后清理所使用过的 Eden 以及 Survivor 区域,并且将这些对象的年龄设置为1,以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年龄 + 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来设定 ),这些对象就会成为老年代。

但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代。

Full GC 是发生在老年代的垃圾收集动作,所采用的是标记-清除算法。

参数

参数详情
-Xms初始堆大小。如:-Xms256m
-Xmx最大堆大小。如:-Xmx512m
-Xmn新生代大小。通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90%
-XssJDK1.5+ 每个线程堆栈大小为 1M,一般来说如果栈不是很深的话, 1M 是绝对够用了的。
-XX:NewRatio新生代与老年代的比例,如 –XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3
-XX:SurvivorRatio新生代中 Eden 与 Survivor 的比值。默认值为 8。即 Eden 占新生代空间的 8/10,另外两个 Survivor 各占 1/10
-XX:PermSize永久代(方法区)的初始大小
-XX:MaxPermSize永久代(方法区)的最大值
-XX:+PrintGCDetails打印 GC 信息
-XX:+HeapDumpOnOutOfMemoryError让虚拟机在发生内存溢出时 Dump 出当前的内存堆转储快照,以便分析用

个人博客
腾讯云社区
掘金
优快云
简书
GitHub
码云
OSCHINA
Segmentfault
公众号:wx.jpg

### 分代垃圾回收算法的原理与实现 分代垃圾回收算法是一种基于对象生命周期特性的内存管理策略,它将堆内存划分为不同的域(代),并针对不同代采用不同的垃圾回收算法以提高效率。以下是分代垃圾回收算法的核心原理和实现方式。 #### 1. 原理 分代垃圾回收算法基于以下两个假设: - **弱世代假设**:大多数对象很快就会变得不可达。即新生的对象通常存活时间较短[^2]。 - **强世代假设**:如果一个对象存活了一段时间,那么它的存活概率会显著增加[^5]。 根据这两个假设,堆内存被划分为新生代(Young Generation)和老年代(Old Generation)。新生代用于存储新创建的对象,而老年代则存放经过多次垃圾回收后仍然存活的对象。 #### 2. 新生代与老年代的划分 - **新生代(Young Generation)** 新生代是垃圾回收的主要目标域,因为大部分对象在此处创建并且很快成为垃圾。新生代通常进一步划分为 Eden 和两个 Survivor (S0 和 S1)。对象首先分配在 Eden ,当 Eden 满时触发 Minor GC,存活的对象会被复制到 Survivor ,经历多次 GC 后仍然存活的对象会被晋升到老年代[^3]。 - **老年代(Old Generation)** 老年代存放的是长期存活的对象。由于老年代对象的存活率较高,因此通常使用标记-清除或标记-整理算法进行垃圾回收[^5]。 #### 3. 实现 分代垃圾回收算法的实现依赖于不同的垃圾回收器,常见的垃圾回收器包括 Serial、ParNew、Parallel Scavenge 等。以下是几种典型的实现方式: - **Serial 收集器** 单线程的垃圾回收器,适用于单核处理器或小型应用。它通过复制算法处理新生代,并使用标记-整理算法处理老年代。 - **ParNew 收集器** 多线程版本的 Serial 收集器,主要负责新生代的垃圾回收,通常与 CMS(Concurrent Mark-Sweep)收集器配合使用。 - **Parallel Scavenge + Parallel Old** 高效的多线程垃圾回收器组合,适用于追求高吞吐量的应用场景。Parallel Scavenge 负责新生代的垃圾回收,而 Parallel Old 负责老年代的垃圾回收。 #### 4. 示例代码 以下是一个简化的伪代码示例,展示如何实现分代垃圾回收的基本逻辑: ```python class GarbageCollector: def __init__(self): self.eden = [] self.survivor_0 = [] self.survivor_1 = [] self.old_gen = [] def allocate(self, obj): self.eden.append(obj) def minor_gc(self): surviving_objects = [obj for obj in self.eden if not self.is_garbage(obj)] for obj in surviving_objects: if obj.age > AGE_THRESHOLD: self.old_gen.append(obj) else: self.survivor_0.append(obj) self.eden.clear() def major_gc(self): surviving_old_objects = [obj for obj in self.old_gen if not self.is_garbage(obj)] self.old_gen = surviving_old_objects def is_garbage(self, obj): # 判断对象是否为垃圾 return False ``` #### 5. 总结 分代垃圾回收算法通过将堆内存划分为新生代和老年代,并针对不同代采用不同的垃圾回收算法,实现了高效的内存管理。这种算法充分利用了对象的生命周期特性,显著提高了垃圾回收的性能[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值