相信不少猿友看到标题就认为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再和各位分享。

本次的分享就到此结束了,希望各位看完都能有所收获,0.0。

转载自一位前辈,地址:http://www.cnblogs.com/zuoxiaolong

JVM内存管理之GC算法精解(五分钟让你彻底明白标记/清除算法)的更多相关文章

  1. GC算法精解(五分钟让你彻底明白标记/清除算法)

    GC算法精解(五分钟让你彻底明白标记/清除算法) 相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底 ...

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

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

  3. JVM内存管理------垃圾搜集器精解(让你在垃圾搜集器的世界里耍的游刃有余)

    引言 在上一章我们已经探讨过hotspot上垃圾搜集器的实现,一共有六种实现六种组合.本次LZ与各位一起探讨下这六种搜集器各自的威力以及组合的威力如何. 为了方便各位的观看与对比,LZ决定采用当初写设 ...

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

    引言 何为终极算法? 其实就是现在的JVM采用的算法,并非真正的终极.说不定若干年以后,还会有新的终极算法,而且几乎是一定会有,因为LZ相信高人们的能力. 那么分代搜集算法是怎么处理GC的呢? 对象分 ...

  5. JVM内存管理之GC算法精解(复制算法与标记/整理算法)

    本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算 ...

  6. JVM内存管理及GC机制

    一.概述 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露 ...

  7. JVM内存管理之GC简介

    为何要了解GC策略与原理?        原因在上一章其实已经有所触及,就是因为在平时的工作和研究当中,不可避免的会遇到内存溢出与内存泄露的问题.如果对GC策略与原理不了解的情况下碰到了前面所说的问题 ...

  8. JVM内存管理------垃圾搜集器参数精解

    本文是GC相关的最后一篇,这次LZ只是罗列一下hotspot JVM中垃圾搜集器相关的重点参数,以及各个参数的解释.废话不多说,这就开始. 垃圾搜集器文章传送门 JVM内存管理------JAVA语言 ...

  9. JVM内存管理之垃圾搜集器参数精解

    本文是GC相关的最后一篇,这次LZ只是罗列一下hotspot JVM中垃圾搜集器相关的重点参数,以及各个参数的解释.废话不多说,这就开始. 垃圾搜集器文章传送门 JVM内存管理------JAVA语言 ...

随机推荐

  1. 控制语句2:循环:for 与 while

    循环是所有编程语言的必备利器,用于重复的动作等等. python中的循环有何特殊性:for 与 while 都有自己的else分支. 要学会刹车: 1.条件的控制次数 2.break 与 contin ...

  2. Prism 4 文档 ---第4章 模块化应用程序开发

    模块化应用程序是指将一个应用程序拆分成一系列的可以组合的功能单元.一个客户端模块封装了应用程序的一部分,并且通常是一系列相关的关注点.它可以包含一个相关的组件的集合,就像用户界面,应用程序功能,和一些 ...

  3. C++实现Prim算法

    闲来无聊,前两天看到一篇关于算法实现的文章.里面又关于图的各种算法介绍,正好上学期还学过图论,现在还记得一点点,先来实现个prim算法: 表示图的文件的内容大体上是这样的: 2.0 1.0 1.0 3 ...

  4. 【LeetCode 67_字符串_算术运算】Add Binary

    string addBinary(string a, string b) { int alen = a.size(); int blen = b.size(); ) return b; ) retur ...

  5. RESTful设计方法

    REST REST,即Representational State Transfer的缩写.维基百科称其为“具象状态传输”,国内大部分人理解为“表现层状态转化”. RESTful是一种开发理念.维基百 ...

  6. New Concept English three(18)

    speed:31w/m 56 words Modern sculpture rarely surprises us any more. The idea that modern art can onl ...

  7. ajaxFileUpload的data数据带pre标签

    解决办法: var ret = jQuery.parseJSON(jQuery(data).text());

  8. Memcached 补充

    Memcached 补充 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站 ...

  9. (转)MapReduce Design Patterns(chapter 7 (part 2))(十四)

    External Source Input Pattern Description 这种模式不从hdfs加载数据,而是从hadoop以外系统,例如RDB或web service加载. Intent 想 ...

  10. 【转】Ubuntu16.04安装WPS

    下载安装下载WPS For Linux:http://community.wps.cn/download/ 直接下载:http://kdl.cc.ksosoft.com/wps-community/d ...