对于Java垃圾回收机制这个问题,一直是Java招聘面试津津乐道的一个问题之一。就好像答不上此问题就证明你不够NX一样。在此将这个问题做一下整理,以备后人方便。
Java语言中一个显着的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制, Java中的对象不再有”作用域”的概念,只有对象的引用才有”作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。
其中垃圾回收中涉及的算法也有好几种,像
引用计数算法;
可达性分析算法(基本思路就是通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索通过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,及说明此对象是不可用的);
标记清除算法(两个阶段:标记和清除,用法:首先标记出需要回收的对象,然后在统一回收。不足:一个是效率问题;另一个是空间问题,标记清楚后会产生大量不连续的内存碎片,空间碎片太多可能会导致程序运行中再分配较大内存时无法找到足够大的内存空间不得不再次出发垃圾回收动作,影响性能);
复制算法(内存划分为大小相等的两块,浪费内存空间,可用内存只有一半的空间。不过商业虚拟机会根据不同比例划分内存,比如最流行的HotSpot会按照8:1的比例划分内存,这样只会浪费一小部分内存空间);
标记整理算法(先标记,然后将存活对象向另一端移动,然后直接清理掉便捷以外的内存);
分代收集算法(目前商业虚拟机都采用的算法,把Java堆划分为新生代和年老代,然后根据各年代特点使用前面最适当的收集算法,比如:新生代中每次回收大量对象死去只有少量存活,那就选用复制算法。这样只需要将存活对象复制,清空掉另一内存区就可以完成垃圾回收。而年老代因为对象存活率高,没有额外的空间对它进行分配担保,就必须使用“标记清除”或者“标记整理”算法来进行垃圾回收)。
垃圾收集器也有很多,比如:Serial收集器,ParNew收集器,Parallel Scavenge收集器,Serial Old收集器,Parallel Old收集器,CMS收集器,G1收集器(当今技术发展最前沿成果之一)。这里就不对各个收集器做赘述了。
以上内容总结来自《深入Java虚拟机》第二版,挺不错的一本书,有需要可以买来拜读一下。
真的很不错
学习学习,研究研究,呵呵