**Java分配对象的过程以及新生代和老年代划分的目的
创建一个新的对象实例时,jvm首先会在堆内存分配内存空间,大部分情况下,新对象都会分配到新生代的Eden区,新生代有三个区,一个Eden区和两个survivor区,当Eden区满了以后会进行Minor GC(新生代GC,是指新生代的垃圾收集,一般Eden区满了就执行,非常频繁,回收速度快),在GC的过程中存活的对象会在两个survivor区中进行转移和交换,经过多次GC任然存活的对象会被放入老年代,老年代主要用于存储长期存活的对象或者是大对象。
新生代中如果有比较大的对象比如数组list那些,会直接放入老年代里面。
划分新生代和老年代的主要目的有两个:
- 新生代采用的是一种简单高效的复制算法进行垃圾回收,可以快速完成垃圾回收减少暂停时间,因为大部分对象都是暂时存在的,所有这种策略能够有效处理大量短暂对象的分配和回收
- 可以针对不同的对象采取不同的回收策略,新生代频繁回收,老年代较少回收,可以减少full GC(全面垃圾收集,清理新生代与老年代以及方法区,full GC通常比Minor GC慢很多,因为full GC涉及到整个栈的回收,并且在GC期间,应用程序的所有线程都会暂停)的频率,提升系统的整体性能
**标记清除、复制和标记压缩三种垃圾回收算法的基本原理
标记清除算法:
遍历所有可达对象标记为存活的状态,然后遍历堆内存,把没有标记的对象全部视为垃圾进行清理
- 优点
简单,不需要额外的内存空间 - 缺点
会产生大量的内存碎片,而且效率很低
复制算法:
把内存分为两个相等的区域,每次只使用其中一个区域,当这个区域满了以后,把存活的对象复制到另一个区域中并且清除原区域的所有对象
- 优点
每次垃圾回收后内存都是连续的,不存在内存碎片 - 缺点
需要额外的占用内存空间,并且对象频繁复制导致效率问题
标记压缩算法:
先标记所有可达对象,然后把存活的对象向一端移动,然后直接清理边界外的内存区域,从而消除碎片
![[Pasted image 20250513172753.png]]
- 优点
解决标记清除算法所造成的内存碎片问题,相对复制算法减少了内存空间占用 - 缺点
复杂度高,而且执行效率相对比较低,特别是压缩阶段需要移动对象,可能会引起程序暂停的时间较长
serial、Parallel、CMS和G1垃圾回收器的主要特点
serial GC是串行垃圾回收器,比较适用于单核处理器或者对响应时间要求不高的场景
Parallel基于多线程并行垃圾回收器,适合高吞吐量的服务器应用或者CPU核心数较多的服务器坏境
CMS也是并且垃圾回收,但是他会把垃圾回收分为四个阶段,尽可能减少了STW(系统在执行特定操作时需暂停所有应用程序线程)的时间,比较适用于高交互性的应用,比如web服务器,以及对停顿时间有严格要求但是对吞吐量比较宽松的场景
G1把堆内存划分了多个大小相等的区域,每个区域都可以独立作为新生代和老年代的一部分,通过并行和并发实现垃圾回收,从而减少停顿时间,另外还能根据目标停顿时间来动态调整垃圾回收策略,来满足不同需求,适合低延迟和可预测的垃圾回收停顿时间的应用,比如大规模分布式系统、在线交易系统