JVM学习记录-垃圾回收算法

简述

因为各个平台的虚拟机的垃圾收集器的实现各有不同,所以只介绍几个常见的垃圾收集算法。

JVM中常见的垃圾收集算法有以下四种:

标记-清除算法(Mark-Sweep)。

复制算法(Copying)。

标记整理算法(Mark-Compact)。

分代收集算法(Generational Collecting)。

标记-清除算法

标记-清除算法是现代垃圾回收算法的思想基础,主要分为两个阶段:标记阶段和清除阶段。首先根据可达分析算法,标记处可以回收的对象,标记完成后,进行清除阶段,将标记为可回收的对象进行清除。这个算法有两个弱点,一个弱点是效率问题,标记和清除效率都不高,另一弱点,也是最大的弱点就是会产生空间碎片。当内存中空间碎片过多时,在创建较大的对象过程中,无法分配出足够的联系内存空间,会不得以的出发一次垃圾回收动作。

标记-清除算法执行过程如下图所示:

复制算法

与标记-清除算法相比,复制算法是一种相对效率高的回收算法,它的核心思想是:将原有的内存空间划分为大小相等的两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活的对象复制到未使用的的内存块中,然后清除正在使用的内存块,然后交换两个内存的角色(即使用块变成未使用块,未使用块变成使用块)。复制算法可以保证回收后没有空间碎片。但是复制算法的弱点是将系统可用内存折半,这个代价有些太大。

执行过程如下:

在JVM的新生代(堆内存分为新生代老年代)中就是使用的这种收集算法,在新生代中大部分对象都是“朝生夕死”,所以复制算法也不是非要按照对半平分内存,而是分为较大的一个Eden空间和两个较小的Survivor空间(from和to),每次进行新生代回收时会将Eden区from Survivor区还存活着的对象复制到to Survivor区,然后清理掉Eden区和from Survivor区的可回收对象,如果to Survivor区中没有足够的空间来接受还存活着的对象,则会把多余的对象放到老年代区。这种改进的(非平分内存)复制算法,既保证了空间的连续性,又避免了大量的内存空间的浪费。

复制算法适用于新生代,是因为在新生代中,垃圾对象通常多于存活对象,这中情况适用复制算法效果会比较好。

标记整理算法

复制算法的高效性,是因为新生代的存活对象多,垃圾对象少。但是在老年代中,常见的情况下大部分都是存活对象,如果依然只用复制算法,效率就会大大折扣。因为存活对象太多,复制的成本太高了。

基于老年代的特点,产生了一种标记整理算法,标记整理算法也是分两个阶段,标记阶段整理阶段,标记阶段也是先标记出存活的对象,在整理阶段是将存活的对象都向内存的一端进行压缩移动,然后清理掉端边界以外的空间。

标记整理算法执行过程如下:

这种算法既避免了产生空间碎片,又不需要将内存平分,因此效率还是可以的。

分代收集算法

当前的商业虚拟机都采用“分代收集算法”,其主要思想是:根据垃圾回收对象的特性,使用合适的算法进行回收。基于这种思想,分代算法将堆内存分为特点鲜明的几块,根据每块的特点,选择适用的收集算法,进而提高回收效率。

在新生代时使用复制算法,在老年代时使用标记压缩算法。

这种分代算法在HotSpot虚拟机上使用,几乎所有的垃圾回收器都区分新生代和老年代。

原文地址:https://www.cnblogs.com/jimoer/p/9000249.html

时间: 2024-10-12 16:25:51

JVM学习记录-垃圾回收算法的相关文章

JVM常见的垃圾回收算法

JVM常见的垃圾回收算法 1.标记-清除算法 标记清除算法也是最基础的算法,就如同他的名字一样,标记清除算法的步骤分为两个步骤,首先标记出需要回收的所有对象,然后在完成标记之后统一清除掉所有被标记的对象,之所以说它是最基础的算法,是因为后续算法都是基于此算法,改进其缺点衍生出来的,标记清除算法有两个缺点,标记和清除这两个步骤都会有性能损耗,且效率低,其次是在完成对象的清除后会留下不连续的内存碎片,算法如下图: 2.复制算法 为了提高效率,我们又引入了复制算法,将现有可用的内存大小均分为二,每次只

谈谈JVM垃圾回收机制及垃圾回收算法

一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理.由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”.垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存. ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其

jvm学习笔记一(垃圾回收算法)

一:垃圾回收机制的原因 java中,当没有对象引用指向原先分配给某个对象的内存时候,该内存就成为了垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃.当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用.事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片.由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,内存会出现碎片.碎片是分配给对象的内存块之间的空闲内存洞.碎片整理将所占用的堆内存移到堆

java虚拟机学习-JVM调优总结-新一代的垃圾回收算法(11)

垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限.但是他无法解决的一个问题,就是Full GC所带来的应用暂停.在一些对实时性要求很高的应用场景下,GC暂停所带来的请求堆积和请求失败是无法接受的.这类应用可能要求请求的返回时间在几百甚至几十毫秒以内,如果分代垃圾回收方式要达到这个指标,只能把最大堆的设置限制在一个相对较小范围内,但是这样有限制了应用本身的处理能力,同样也是不可接收的. 分代垃圾回收方式确实也考虑了实时性要求而

记录JVM垃圾回收算法

垃圾回收算法可以分为三类,都基于标记-清除(复制)算法: Serial算法(单线程) 并行算法 并发算法 JVM会根据机器的硬件配置对每个内存代选择适合的回收算法,比如,如果机器多于1个核,会对年轻代选择并行算法. 稍微解释下的是,并行算法是用多线程进行垃圾回收,回收期间会暂停程序的执行,而并发算法,也是多线程回收,但期间不停止应用执行.所以,并发算法适用于交互性高的一些程序.经过观察,并发算法会减少年轻代的大小,其实就是使用了一个大的年老代,这反过来跟并行算法相比吞吐量相对较低. 还有一个问题

JVM学习记录2--垃圾回收算法

首先要明确,垃圾回收管理jvm的堆内存,方法区是堆内存的一部分,所以也是. 而本地方法栈,虚拟机栈,程序计数器随着线程开始而产生,线程的结束而消亡,是不需要垃圾回收的. 1. 判断对象是否可以被回收 1.1 引用计数法 原理:给对象添加一个计数标志,被引用一次就加1,引用取消就减1,而垃圾回收时只需要回收计数值为0的即可. 优点:快,简单 缺点:无法解决循环引用,如A引用B,B引用A,然后A,B的计数值都是1,但实际上A,B都应该被回收. 1.2 根搜索算法 原理:通过一系列名为"GC Root

03 JVM 从入门到实战 | 简述垃圾回收算法

引言 之前我们学习了 JVM 基本介绍 以及 什么样的对象需要被 GC ,今天就来学习一下 JVM 在判断出一个对象需要被 GC 会采用何种方式进行 GC.在学习 JVM 如何进行垃圾回收方法时,发现所谓的 JVM 垃圾回收思想和现实生活的场景有很多相似的地方.所以本文用餐厅回收餐桌的方式类比 JVM 垃圾回收算法,应该能帮助 JVM 学习的理解和记忆. 经典垃圾回收算 标记-清除(Mark-Sweep) 研发园开了家新餐厅,餐厅老板在考虑如何回收餐盘时首先使用了最简单的方式,那就是服务员在顾客

JVM优化 垃圾回收 算法 垃圾收集器 GC日志可视化查看

今日内容了解什么是垃圾回收掌握垃圾会回收的常见算法学习串行.并行.并发.G1垃圾收集器学习GC日志的可视化查看 1.什么是垃圾回收?程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存 资源,最终将导致内存溢出,所以对内存资源的管理是非常重要了. 1.1.C/C++语言的垃圾回收在C/C++语言中,没有自动垃圾回收机制,是通过new关键字申请内存资源,通过delete 关键字释放内存资源.如果,程序员在某些位置没有写delete进行释放,那么申请的对象将一直占用内存资源,

JVM垃圾回收机制总结(4) :新一代的垃圾回收算法

全文转载: http://pengjiaheng.iteye.com/blog/548472 垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限.但是他无法解决的一个问题,就是Full GC所带来的应用暂停.在一些对实时性要求很高的应用场景下,GC暂停所带来的请求堆积和请求失败是无法接受的.这类应用可能要求请求的返回时间在几百甚 至几十毫秒以内,如果分代垃圾回收方式要达到这个指标,只能把最大堆的设置限制在一个相对较小范围内,但