这里LZ给各位总结一下三个算法的共同点以及它们各自的优势劣势,让各位对比一下,想必会更加清晰。
它们的共同点主要有以下两点。
- 三个算法都基于根搜索算法去判断一个对象是否应该被回收,而支撑根搜索算法可以正常工作的理论依据,就是语法中变量作用域的相关内容。因此,要想防止内存泄露,最
根本的办法就是掌握好变量作用域,而不应该使用前面内存管理杂谈一章中所提到的
C/C++式内存管理方式。
- 在GC线程开启时,或者说GC过程开始时,它们都要暂停应用程序(stop the world)。
它们的区别LZ按照下面几点来给各位展示。(>表示前者要优于后者,=表示两者效果一样)
效率:复制算法>标记/整理算法>标记/清除算法(此处的效率只是简单的对比时间复杂度,实际情况不一定如此)。
内存整齐度:复制算法=标记/整理算法>标记/清除算法。
内存利用率:标记/整理算法=标记/清除算法>复制算法。
可以看到标记/清除算法是比较落后的算法了,但是后两种算法却是在此基础上建立的,俗话说"吃水不忘挖井人",因此各位也莫要忘记了标记/清除这一算法前辈。而且,在某些时候,标记/清除也会有用武之地。
为什么JVM中复制算法和标记-整理算法的效率问题? 书里面还有博客都说复制算法的效率是优于标记-整理算法的,我个人的理解是复制算法是先标记然后整体复制到另一边,标记-整理是先标记然后整理在一起,我觉得整理和复制的算法是差不多的,想问下大佬们这两个算法的差别在哪里呢
都是从gc roots判断区域内哪些是存活的,复制算法只用检索一般的区域,另一半是供复制用的。标记整理要检索整个区域。每次检索标记整理都比复制算法检索的区域大,当然费时间了。但是复制算法也因此浪费了一半空间,所以空间利用率不高。我是这样理解的,不知道对不对。总的来说复制算法要检索一般区域,而标记整理算法要检索整个区域。
这些算法没有绝对的高效,只有在哪个代的效率最高的区别,没有谁好谁不好的问题,复制算法适用于新生代,因为垃圾很多。标记整理适用于老年代,因为垃圾很少。这样才能将算法高效化,而不是赤裸裸去比较算法好坏
结束语
到此我们已经将三个算法了解清楚了,可以看出,效率上来说,复制算法是当之无愧的老大,但是却浪费了太多内存,而为了尽量兼顾上面所提到的三个指标,标记/整理算法相对来说更平滑一些,但效率上依然不尽如人意,它比复制算法多了一个标记的阶段,又比标记/清除多了一个整理内存的过程。
难道就没有一种最优算法吗?
当然是没有的,这个世界是公平的,任何东西都有两面性,试想一下,你怎么可能找到一个又漂亮又勤快又有钱又通情达理,性格又合适,家境也合适,身高长相等等等等都合适的女人?就算你找到了,至少有一点这个女人也肯定不满足,那就是多半不会恰巧又爱上了与LZ相似的各位苦逼猿友们。你是不是想说你比LZ强太多了,那LZ只想对你说,高富帅是不会爬在电脑前看技术文章的,0.0。
但是古人就是给力,古人说了,找媳妇不一定要找最好的,而是要找最合适的,听完这句话,瞬间感觉世界美好了许多。
算法也是一样的,没有最好的算法,只有最合适的算法。
既然这三种算法都各有缺陷,高人们自然不会容许这种情况发生。因此,高人们提出可以根据对象的不同特性,使用不同的算法处理,类似于萝卜白菜各有所爱的原理。于是奇迹发生了,高人们终于找到了GC算法中的神级算法-----分代搜集算法。
至于这个神级算法是如何处理的,LZ就在下一章再和各位猿友探讨了,本次就到此为止了,希望各位有所收获。
原文地址:https://www.cnblogs.com/qingruihappy/p/9691376.html