买东西最便宜的网站,手机设计图软件app,重庆公司注册地址提供,成都移动网站建设转载自 JVM内存管理------GC算法精解#xff08;五分钟让你彻底明白标记/清除算法#xff09;相信不少猿友看到标题就认为LZ是标题党了#xff0c;不过既然您已经被LZ忽悠进来了#xff0c;那就好好的享受一顿算法大餐吧。不过LZ丑话说前面哦#xff0c;这篇文章应该能让…转载自 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再和各位分享。