当Java应用程序运行时,它在堆内存中分为新生代(Young Generation)、老年代(Old Generation)和持久代(Permanent Generation,Java 8之后被元数据区替代)等几个区域。新生代主要用于存放新创建的对象,而垃圾回收主要集中在新生代进行。
新生代(Young Generation):包括三个区域,Eden空间和两个Survivor空间(通常命名为S0和S1)。对象首先在Eden空间分配,经过一轮Minor GC 后如果仍然存活,则会被移到Survivor空间,经过多次(minor15次,cms收集器默认6次)后会晋升到老年代。当然可以自己设置次数,下面是官方文档
**注意:**即使对象的年龄尚未达到设定的阈值,如果Survivor区中的空间占用超过50%,这些对象也可能被提前晋升到老年代。这是因为为了避免Survivor区溢出,JVM可能会进行提前晋升。
结论–>动态年龄判断: Survivor 区的对象年龄从小到大进行累加,当累加到 X 年龄 (某个年龄)时占用空间的总和大于50% (可以使用-XX:TargetSurvivorRatio=? 来设置保留多少空闲空间,默认值是 50) ,那么比 X 年龄大的对象都会晋升到老年代 3. 这两个可以查看垃圾回收器默认值
老年代(Old Generation):用于存放生命周期较长的对象,经过多次Minor GC(15次的s区域来回回收,这里次数也称为年龄,即15岁进入到老年代)或者经过一次Full GC后的对象会晋升到这个区域。
持久代(Permanent Generation):在Java 7及之前,主要用于存放类的元数据信息,包括类的结构、方法等。在Java 8及之后,被元数据区替代。
新生代的垃圾回收主要分为两个阶段:Minor GC和Full GC。
触发条件: 当Eden空间满时触发Minor GC。
回收过程:
特点:
触发条件: 在老年代空间不足时触发Full GC。或者是由于Minor GC过程中晋升到老年代的平均大小大于老年代的剩余空间时。
回收过程:
特点:
新生代的垃圾回收主要通过Minor GC来清理Eden空间和Survivor空间,快速回收短时间内创建的对象。而Full GC则是针对整个堆内存进行的,较为耗时。这种分代垃圾回收的策略有效提高了垃圾回收的效率,延长了老年代的垃圾回收触发时间,提高了整体的应用程序性能。
老年代空间分配担保机制是Java虚拟机为了避免由于新生代Minor GC导致的空间不足而触发一次Full GC,从而提高垃圾回收效率的一种机制。具体而言,它保证了在发生Minor GC时,虚拟机在老年代预留一定的内存空间,以应对新生代对象晋升到老年代的情况。
这个机制的设计基于这样一个考虑:在一次Minor GC之前,虚拟机会首先检查老年代的剩余空间是否大于新生代所有对象的总空间,如果是,那么Minor GC可以放心进行。如果不足以容纳新生代所有对象,那么虚拟机会查看老年代中的存活对象是否能够在某个特定的年龄阈值之下就能被全部安置到老年代,如果这个条件成立,同样触发Minor GC,否则,进行一次Full GC。
这个担保机制的核心思想是为了尽量避免因为新生代对象晋升导致的Full GC。因为Minor GC的频率通常比Full GC低得多,而且Minor GC的速度更快,因此通过老年代空间分配担保机制,可以在大多数情况下避免因为新生代GC而触发Full GC,提高了垃圾回收的效率。
躲过 15 次 GC之后进入老年代,可通过JVM 参数“-XX:MaxTenuringThreshold”来设 置年龄,默认为 15 岁
2、动态对象年龄判断
3、老年代空间担保机制
4、大对象直接进入老年代
在Java中,垃圾回收是一项重要的技术,通过自动管理内存资源,使得开发者可以更专注于业务逻辑的实现而不用过多关心内存的分配和释放。通过深入理解垃圾回收机制,我们可以更好地优化代码,提高程序性能,确保系统的稳定性和可维护性。
感谢您的阅读,希望本文对您理解和应用Java中的垃圾回收机制有所帮助。如果有任何疑问或建议,欢迎留言交流,共同学习进步。谢谢!