现代编程语言通常采用垃圾回收机制来自动管理内存。垃圾回收机制是一种自动化的内存管理技术,可以在程序运行时自动识别和回收不再使用的内存,从而减少内存泄漏和其他内存相关问题的发生。
本文将介绍垃圾回收算法和垃圾回收器的相关知识,帮助读者深入了解内存管理的实现原理和技术细节。
目录
前言:
常见的垃圾回收算法:
1.标记-清除算法(Mark Sweep GC)
2.复制算法(Copying GC)
3.标记整理算法(Mark Compact GC)
4.分代GC(Generational GC)
年轻代:
老年代:
分代GC的垃圾回收流程:
总结:
垃圾回收的要做的事就两件:
1.找到内存中存活的对象,并进行分类
2.回收分类后需要被回收的对象
而所有的垃圾回收算法,都是围绕着这两步走的,我们一起来学习一下常见的垃圾回收算法:
标记阶段:
清除阶段:
标记-清除算法的优点:
标记-清除算法的缺点:
总之,标记-清除算法是一种常见的垃圾回收算法,通过标记活动对象和清除垃圾对象来管理内存。然而,由于其产生的内存碎片和长时间的停顿,它可能不适用于对内存使用效率和应用程序响应时间要求较高的场景。
该算法将可用内存空间划分为两个相等大小的半区,每次只使用其中一个半区,称为活动半区,而另一个半区称为闲置半区。当活动半区的内存空间用尽时,会触发垃圾回收操作。
复制算法的优点:
复制算法的缺点:
标记阶段:
整理阶段:
清除阶段:
标记-整理算法的优点:
标记-整理算法的缺点:
通常,堆内存被划分为年轻代(Young Generation)和老年代(Old Generation)两个部分:
年轻代用于存放新创建的对象,
老年代用于存放存活时间较长的对象。
在年轻代中,采用了复制算法进行垃圾回收。当年轻代的空间不足时,会触发一次新生代垃圾回收。这时,所有存活的对象会被复制到另一个存活区域,非存活的对象则会被回收。复制算法的优点是简单高效,但缺点是浪费了一部分内存空间。
年轻代的常用JVM参数:
1.Eden区
Eden区是新生代中最大的内存区域,用于存放新创建的对象。调优参数如下:
2.Survivor区
Survivor区用于存放从Eden区复制过来的存活对象。调优参数如下:
在老年代中,采用了标记-清除(Mark-Sweep)或标记-整理(Mark-Compact)算法进行垃圾回收。当老年代的空间不足时,会触发一次老年代垃圾回收。标记-清除算法首先标记出所有存活的对象,然后清除掉未标记的对象;而标记-整理算法则会将存活的对象往一端移动,然后清理掉边界以外的内存空间。这两种算法的优点是可以处理大对象和长期存活的对象,但缺点是可能会产生内存碎片。
分代GC利用了年轻代中大量对象的短生命周期的特征,通过频繁回收年轻代来提高垃圾回收的效率。同时,老年代中较少的存活对象减少了垃圾回收的频率,提高了整体的垃圾回收效率。
总之,分代GC是一种根据对象生命周期特征划分堆内存并采取不同的垃圾回收策略的方法,可以有效提高垃圾回收的效率和性能。希望这次的回答能够满足您的需求,如有其他问题,请随时提问。
年轻代回收:
需要注意的是:每一次Minor GC 之后,都会为存活的对象记录年龄,初始值为0,每一次存活加1。当年龄超过某个阈值的时候,就会进入老年代。 年龄设定阈值最大是15。
老年代回收:
当不断有对象进入老年代,老年代空间不足之后,他会首先尝试Minor GC,尝试清理 年轻代的空间
因为在老年代的有些对象 会出现年龄没有达到阈值 的情况,这是因为如果 年轻代 在存储新对象的时候,通过Minor GC仍然无法让出足够的 内存,那么年轻代中一些年龄比较大的对象就会被年轻代放入到老年代当中。此时老年代可以尝试把这些对象返送给年轻代。
当Minor GC 仍然无法缓解老年代的空间不足时,就会触发Full GC。此时会对整个堆进行垃圾回收。而FULL GC的时候 老年代这块采用的算法 就是 标记清除法 或者 标记整理法。
当FULL GC 仍然无法缓解老年代的空间不足的时候,如果再有对象存入老年代,就会抛出 OUT OF MEMORY 异常。
总的来说。文章介绍了几种常见的垃圾回收算法,包括标记-清除算法,标记-整理算法,复制算法,和分代GC
标记-清除算法通过标记活动对象并清除垃圾对象来管理内存,但可能会产生内存碎片并导致较长的停顿时间。相比之下,标记-整理算法在清除阶段进行内存整理,消除内存碎片并提供较少的停顿时间,适用于对内存利用效率和应用程序响应时间要求较高的场景。
综合考虑,选择合适的垃圾回收算法取决于具体的应用需求和环境特点。在实际应用中,也可以根据情况结合不同算法以获得更好的性能和效果。最终目标是提高内存利用效率、减少内存碎片和保证应用程序的响应性能。
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!