JVM内存管理------GC算法精解(五分钟让你彻底明白标记/清除算法)

转载自  JVM内存管理------GC算法精解(五分钟让你彻底明白标记/清除算法)

相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧。不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内看完,那就不是LZ的错啦。

       好了,前面只是小小开个玩笑,让各位猿友放松下心情。下面即将与各位分享的,是GC算法中最基础的算法------标记/清除算法。如果搞清楚这个算法,那么后面两个就完全是小菜一碟了。

       首先,我们回想一下上一章提到的根搜索算法,它可以解决我们应该回收哪些对象的问题,但是它显然还不能承担垃圾搜集的重任,因为我们在程序(程序也就是指我们运行在JVM上的JAVA程序)运行期间如果想进行垃圾回收,就必须让GC线程与程序当中的线程互相配合,才能在不影响程序运行的前提下,顺利的将垃圾进行回收

       为了达到这个目的,标记/清除算法就应运而生了。它的做法是当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整个程序(也被成为stop the world),然后进行两项工作,第一项则是标记,第二项则是清除

       下面LZ具体解释一下标记和清除分别都会做些什么。

       标记:标记的过程其实就是,遍历所有的GC Roots,然后将所有GC Roots可达的对象标记为存活的对象。

       清除:清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。

       其实这两个步骤并不是特别复杂,也很容易理解。LZ用通俗的话解释一下标记/清除算法,就是当程序运行期间,若可以使用的内存被耗尽的时候,GC线程就会被触发并将程序暂停,随后将依旧存活的对象标记一遍,最终再将堆中所有没被标记的对象全部清除掉,接下来便让程序恢复运行

       下面LZ给各位制作了一组描述上面过程的图片,结合着图片,我们来直观的看下这一过程,首先是第一张图。

          这张图代表的是程序运行期间所有对象的状态,它们的标志位全部是0(也就是未标记,以下默认0就是未标记,1为已标记),假设这会儿有效内存空间耗尽了,JVM将会停止应用程序的运行并开启GC线程,然后开始进行标记工作,按照根搜索算法,标记完以后,对象的状态如下图。

         可以看到,按照根搜索算法,所有从root对象可达的对象就被标记为了存活的对象,此时已经完成了第一阶段标记。接下来,就要执行第二阶段清除了,那么清除完以后,剩下的对象以及对象的状态如下图所示。

         可以看到,没有被标记的对象将会回收清除掉,而被标记的对象将会留下,并且会将标记位重新归0。接下来就不用说了,唤醒停止的程序线程,让程序继续运行即可。

  

         其实这一过程并不复杂,甚至可以说非常简单,各位说对吗。不过其中有一点值得LZ一提,就是为什么非要停止程序的运行呢?

         这个其实也不难理解,LZ举个最简单的例子,假设我们的程序与GC线程是一起运行的,各位试想这样一种场景。

         假设我们刚标记完图中最右边的那个对象,暂且记为A,结果此时在程序当中又new了一个新对象B,且A对象可以到达B对象。但是由于此时A对象已经标记结束,B对象此时的标记位依然是0,因为它错过了标记阶段。因此当接下来轮到清除阶段的时候,新对象B将会被苦逼的清除掉。如此一来,不难想象结果,GC线程将会导致程序无法正常工作。

         上面的结果当然令人无法接受,我们刚new了一个对象,结果经过一次GC,忽然变成null了,这还怎么玩?

         

         到此为止,标记/清除算法LZ已经介绍完了,下面我们来看下它的缺点,其实了解完它的算法原理,它的缺点就很好理解了。

         1、首先,它的缺点就是效率比较低(递归与全堆对象遍历),而且在进行GC的时候,需要停止应用程序,这会导致用户体验非常差劲,尤其对于交互式的应用程序来说简直是无法接受。试想一下,如果你玩一个网站,这个网站一个小时就挂五分钟,你还玩吗?

         2、第二点主要的缺点,则是这种方式清理出来的空闲内存是不连续的,这点不难理解,我们的死亡对象都是随即的出现在内存的各个角落的,现在把它们清除之后,内存的布局自然会乱七八糟。而为了应付这一点,JVM就不得不维持一个内存的空闲列表,这又是一种开销。而且在分配数组对象的时候,寻找连续的内存空间会不太好找。

         看完它的缺点估计有的猿友要忍不住吐糟了,“这么说这个算法根本没法用嘛,那LZ还介绍这么个玩意干什么。”

         猿友们莫要着急,一个算法有缺点,高人们自然会想尽办法去完善它的。而接下来我们要介绍的两种算法,皆是在标记/清除算法的基础上优化而产生的。具体的内容,下一次LZ再和各位分享。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙 电视 安卓,华为鸿蒙2.0来了!打通手机、电视、PC全平台,Mate 40 整装齐发...

华为鸿蒙2.0来了!打通手机、电视、PC全平台,Mate 40 整装齐发2020-07-05 15:52:041点赞0收藏1评论7月5日消息,据国外知名爆料玩家 Teme 透露,华为今年秋季发布会上除了将发布华为 Mate 40 系列旗舰机型外,还将带来 EMU…

跳槽穷半年,改行穷三年,说的太好了!

跳槽穷半年,改行穷三年。献给每天喊辞职、想辞职的人或周期性喊辞职、想辞职的人! 1 不要轻易离开团队,否则你要从零做起 。2 不要老想着做不顺就放弃,哪个团队都有问题,哪个团队都有优点。3 .跟对领导很重要&#xff…

JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法)

转载自 JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法)引言何为终极算法?其实就是现在的JVM采用的算法,并非真正的终极。说不定若干年以后,还会有新的终极算法,而且几乎是一定会有&…

android 应用程序 判断 ,如何判断Android应用程序是否正在前台运行?

慕的地6264312或者,您可以检查ActivityManager哪些任务正在按getRunningTasks方法运行。然后,检查返回的任务列表中的第一个任务(前景中的任务)是否是您的任务。这是代码示例:public Notification buildNotification(String arg0, Map arg1) …

在离线环境中使用.NET Core

0x00 写在开始 很早开始就对.NET Core比较关注,一改微软之前给人的印象,变得轻量、开源、跨平台。最近打算试着在工作中使用。但工作是在与互联网完全隔离的网络中进行的,因此就开始了在离线环境中部署.NET Core开发环境的尝试。总的来说还是…

java常量池技术

转载自 java常量池技术摘要: 简介 常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s "java"这种…

华为荣耀5a是android几,华为荣耀5a各版本区别 华为荣耀5a各版本 对比【图文】

一个多月前,华为发布了华为荣耀5a,相信不少人都对这部手机十分期待。这款产品主打Slogan是“青春好拍档”。延续了5系列的定位,不仅价格便宜还拥有不错的拍照及音质调教。那么华为荣耀畅玩5A有几个版本?各版本有什么区别?下面小编就带来华为…

.NET程序员走向高端必读书单汇总

如今程序开发工作越来越简单(丰富的API、智能的IDE、越来越多的开发框架),普通人通过简单的训练,通过组合和复制就能完成众多程序的功能。因此程序员这种过去高技术职业的代名词,现在却如此低贱,被称之为码农。借用微观经济学原理…

android roboguice2,Android快速开发框架 roboguice

//使用框架前class AndroidWay extends Activity {TextView name;ImageView thumbnail;LocationManager loc;Drawable icon;String myName;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);name (TextVi…

java 为什么需要常量池

转载自 java 为什么需要常量池java中讲的常量池,通常指的是运行时常量池,它是方法区的一部分,一个jvm实例只有一个运行常量池,各线程间共享该运行常量池。 java内存模型中将内存分为堆和栈,其中堆为线程间共享的内存数…

.NET Core第三方开源Web框架YOYOFx

YOYOFx框架 YOYOFx是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台。 本着学习的态度,造了这个轮子,也是为了更好的了解各个框架的原理和有点,还希望可以和大家多交流 。 GitHub:https://github.co…

JavaScript实现搜索框效果

要求&#xff1a;搜索框获取焦点的时候如果里面的内容是“请输入关键字”&#xff0c;则清空&#xff0c;否则不清空 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">…

JVM调优总结(1):一些概念

转载自 JVM调优总结&#xff08;1&#xff09;&#xff1a;一些概念数据类型Java虚拟机中&#xff0c;数据类型可以分为两类&#xff1a;基本类型和引用类型。基本类型的变量保存原始值&#xff0c;即&#xff1a;他代表的值就是数值本身&#xff1b;而引用类型的变量保存引用…

android通讯录增删改查,android 通话记录的增删改查 .

//获取当前的手机号public String getLocalNumber() {Context context getApplicationContext();TelephonyManager tManager (TelephonyManager)context.getSystemService(TELEPHONY_SERVICE);String number tManager.getLine1Number();return number;}//删除通话记录privat…

使用C#进行系统编程

虽然对于系统编程&#xff08;System programming&#xff09;的定义很模糊&#xff0c;不过可以将其描述为在比特、字节、指令&#xff0c;或CPU周期层面所进行的思考。系统编程这个概念也暗含了对性能和可靠性的需求。Microsoft技术总监Joe Duffy在QCon New York活动中介绍了…

html表格转换为csv,python实现将html表格转换成CSV文件的方法

python实现将html表格转换成CSV文件的方法发布于 2015-11-18 16:53:39 | 155 次阅读 | 评论: 0 | 来源: 网友投递Python编程语言Python 是一种面向对象、解释型计算机程序设计语言&#xff0c;由Guido van Rossum于1989年底发明&#xff0c;第一个公开发行版发行于1991年。Pyth…

JVM调优总结(2):基本垃圾回收算法

转载自 JVM调优总结&#xff08;2&#xff09;&#xff1a;基本垃圾回收算法可以从不同的的角度去划分垃圾回收算法&#xff1a; 按照基本回收策略分 引用计数&#xff08;Reference Counting&#xff09;: 比较古老的回收算法。原理是此对象有一个引用&#xff0c;即增加一个…

巧妙使用信用卡N个小技巧

大家看标题也看出来了&#xff0c;今天的博文与之前的相差十万八千里&#xff0c;既不是代码&#xff0c;也不是黑科技&#xff0c;既不属于创业&#xff0c;也不属于赚钱&#xff0c;今天咱们坐下来就慢慢的谈谈信用卡吧&#xff0c;现在大多数白领&#xff0c;老板&#xff0…

ubuntu16.4下用jexus部署asp.net core rtm

今天说下ubuntu 下部署asp.net core&#xff0c;不需要安装.net core sdk&#xff0c;自带运行时方式部署&#xff0c;利用jexus服务器转发请求到asp.net core. 1.部署准备环境 vmware虚拟机&#xff08;其他也可以&#xff09; ubuntu16.04镜像 2.发布环境 win10系统 vs2015 u…

html页面会出现浏览器崩溃,大规模WebGL应用引发浏览器崩溃的几种情况及解决办法...

我们使用Javascript写WebApp的时候&#xff0c;一般都不会考虑对象的生命周期&#xff0c;不太关注内存“泄露”的问题&#xff0c;依赖JS引擎的垃圾回收机制就可以运行的很好&#xff0c;基本上很少会出现浏览器崩溃的情况。但在Web端显示大规模三维模型的时候&#xff0c;内存…