深入理解JVM一垃圾回收算法
我们都知道java语言与C语言最大的区别就是内存自动回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理。
一、stop the world
在介绍垃圾回收算法之前,我们需要先了解一个词“stop the world”,stop the world会在执行某一个垃圾回收算法的时候产生,JVM为了执行垃圾回收,会暂时java应用程序的执行,等垃圾回收完成后,再继续运行。如果你使用JMeter测试过java程序,你可能会发现在测试过程中,java程序有不规则的停顿现象,其实这就是“stop the world”,停顿的时候JVM是在做垃圾回收。所以尽可能减少stop the world的时间,就是我们优化JVM的主要目标。接下来我们看一下目前有哪些常见垃圾回收的算法。
二、引用计数法
引用计数法顾名思义,就是对一个对象被引用的次数进行计数,当增加一个引用计数就加1,减少一个引用计数就减1。

上图表示3个Teacher的引用指向堆中的Teacher对象,那么Teacher对象的引用计数就是3,以此类推Student对象的引用计数就是2。

上图表示Teacher对象的引用减少为2,Student对象的引用减少为0(减少的原因是该引用指向了null,例如teacher3=null),按照引用计数算法,Student对象的内存空间将被回收掉。
引用计数算法原理非常简单,是最原始的回收算法,但是java中没有使用这种算法,原因有2。1是频繁的计数影响性能,2是它无法处理循环引用的问题。
例如Teacher对象中引用了Student对象,Student对象中又引用了Teacher对象,这种情况下,对象将永远无法被回收。
三、标记清除
标记清除算法,它是很多垃圾回收算法的基础,简单来说有两个步骤:标记、清除。
标记:遍历所有的GC Roots,并将从GC Roots可达的对象设置为存活对象;
清除:遍历堆中的所有对象,将没有被标记可达的对象清除;

注意上图灰色的对象,因为从GC Root遍历不到它们(尽管它们本身有引用关系,但从GC Root无法遍历到它们),因此它们没有被标记为存活对象,在清除过程中将会被回收。
这里需要注意的是标记清除算法执行过程中,会产生“stop the world”,让java程序暂停等待以保证在标记清除的过程中,不会有新的对象产生。为什么必须暂停java程序呢?举个例子,如果在标记过程完成后,又新产生了一个对象,而该对象已经错过了标记期,那么在接下来的清除流程中,这个新产生的对象因为未被标记,所以将被视为不可达对象而被清除,这样程序就会出错,因此标记清除算法在执行时,java程序将被暂停,产生“stop the world”。
接下来我们总结一下标记清除算法:
1、因为涉及大量的内存遍历工作,所以执行性能较低,这也会导致“stop the world”时间较长,java程序吞吐量降低;
2、我们注意到对象被清除之后,被清除的对象留下内存的空缺位置,造成内存不连续,空间浪费。
接下来我们看一下其他算法能不能改善这些问题?
四、标记压缩
标记压缩算法你可能已经想到了,它就是在标记清除算法的基础上,增加了压缩过程。

在进行完标记清除之后,对内存空间进行压缩,节省内存空间,解决了标记清除算法内存不连续的问题。
注意标记压缩算法也会产生“stop the world”,不能和java程序并发执行。在压缩过程中一些对象内存地址会发生改变,java程序只能等待压缩完成后才能继续。
五、复制算法
复制算法简单来说就是把内存一分为二,但只使用其中一份,在垃圾回收时,将正在使用的那份内存中存活的对象复制到另一份空白的内存中,最后将正在使用的内存空间的对象清除,完成垃圾回收。




复制算法相对标记压缩算法来说更简洁高效,但它的缺点也显而易见,它不适合用于存活对象多的情况,因为那样需要复制的对象很多,复制性能较差,所以复制算法往往用于内存空间中新生代的垃圾回收,因为新生代中存活对象较少,复制成本较低。它另外一个缺点是内存空间占用成本高,因为它基于两份内存空间做对象复制,在非垃圾回收的周期内只用到了一份内存空间,内存利用率较低。
六、小结
以上我们介绍了常见的垃圾回收算法,这些算法各有各的优缺点,但在JVM中并不是单纯的使用特定的算法,而是使用的一种叫垃圾回收器的东西,垃圾回收器可以看做一系列算法的不同组合,在不同的场景使用合适的垃圾回收器,才能起到事半功倍的效果。
本文转自:https://www.cnblogs.com/leefreeman/p/7389919.html
深入理解JVM一垃圾回收算法的更多相关文章
- 深入理解JVM(五) -- 垃圾回收算法
上篇文章我们了解到哪些内存区域和哪些对象可以被回收,这篇文章我们就来了解一下具体的垃圾回收算法的思路,不讨论具体的实现. 一 最基础算法 标记-清除(Mark-Swap) 为什么说他是最基础的算法,因 ...
- JVM(九):垃圾回收算法
JVM(九):垃圾回收算法 在本文中,我们将从概念模型的角度探讨 JVM 是如何回收对象,包括 JVM 是如何判断一个对象已经死亡,什么时候在哪里进行了垃圾回收,垃圾回收有几种核心算法,每个算法优劣是 ...
- jvm详情——3、JVM基本垃圾回收算法回收策略
JVM基本垃圾回收算法回收策略 引用计数(Reference Counting):比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的 ...
- JVM G1垃圾回收算法简要介绍
JVM G1垃圾回收算法简要介绍 G1的特点 能够像CMS垃圾回收算法一样并发操作应用线程(潜台词:多核) 无需太长时间即可压缩空闲内存空间(潜台词:不会引起太多的GC停顿时间) 尽可能地让GC时长可 ...
- jvm的垃圾回收算法
一.对象存活判断判断对象是否存活一般有两种方式:1.引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收.此方法简单,无法解决对象相互循环引用的问题.2 ...
- 深入探究JVM之垃圾回收算法实现细节
@ 目录 前言 垃圾回收算法实现细节 根节点枚举 安全点 安全区域 记忆集和卡表 写屏障 并发的可达性分析 低延迟GC Shenandoah ZGC 总结 前言 本篇紧接上文,主要讲解垃圾回收算法的实 ...
- JVM常见垃圾回收算法
jdk1.7.0_79 众所周知,Java是一门不用程序员手动管理内存的语言,全靠JVM自动管理内存,既然是自动管理,那必然有一个垃圾内存的回收机制或者回收算法.本文将介绍几种常见的垃圾回收(下文简称 ...
- jvm学习-垃圾回收算法(三)
垃圾回收算法 引用计数法 比较古老的一种垃圾回收算法.在java的GC并没有采用 增加一个引用 引用+1 减少一个引用引用减一 每次清除引用为0的的对象 缺点:不能回收循环引用的垃圾对象 标记清除 ...
- 深入理解JVM——关于垃圾回收
关于垃圾回收 仿佛来自上海居委会大妈的灵魂拷问:“你是什么垃圾?” 不 今天我们要说的是JVM的垃圾回收 假如我是一个“人”类的“对象”,也和人的生命一样必有一死,可是“我真的还想再活500年~~”, ...
随机推荐
- 成都Uber优步司机奖励政策(4月14日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- dsp6657的helloworld例程测试-第二篇-CFG文件
1. 上一篇疑问,int StackTest()这个函数是怎么运行的,后来在.cfg文件找到了答案,.cfg包含丰富的信息,对于用惯C语言的,确实不太习惯 var Memory = xdc.useMo ...
- MySQL数据库之单双表查询
单表查询 先创建表 #创建表 create table employee( id int not null unique auto_increment, name varchar(20) not nu ...
- 002 -- MySQL的逻辑架构
msql的逻辑架构图 第一层:主要功能是连接处理.授权认证.安全等.相当于JavaEE中的常说的Web层 第二层:包含了 ...
- Ubuntu18.04重装指南
Guide google chrome sougou 谷歌服务助手\(\rightarrow\)谷歌访问助手(谷歌应用商店)登录谷歌账号(cnyalitea@gmail.com)然后同步. \(\te ...
- Hackerank-Array-NewYearChaos
题目背景描述 新年第一天,N 个人排队坐过山车.每个人穿有带编号的衣服 \([1, 2, 3, ...]\). 因为排队时间太久,有人发现给前面相邻的人喂一颗糖,就可以和他交换位置,而每人手里只有两颗 ...
- jquery新版本旧版本之间的坑
JQuery自1.6.1版本开始增加一些属性,使用时尽量使用这些新的属性,例如:selected.checked.在高版本中赋值时最好用prop,如果用attr就会出现赋值不成功的问题, 一般自定义属 ...
- HDU 5496 Beauty of Sequence
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5496 Beauty of Sequence Problem Description Sequence ...
- Mac10.11.2 Apache 服务配置
系统默认是隐藏apache安装目录的,但我们可以通过“命令行”或者“文件夹前往”的方式找到它.它是安装在系统的私有目录下,也就是/private/etc下面,因为它是隐藏的,所以我们无法通过界面找到它 ...
- n元一维向量向左循环移位i的几种算法
1.最简单的算法借助于一个n元的中间向量在n步时间内完成 时间复杂度:O(n) 空间复杂度O(n) void shift_easy(int arr[], int _arr[], int n, int ...