jAVA 初识jvm(五)
- 什么是垃圾?
在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。
垃圾回收算法
引用技术算法(标记阶段)
对每个对象保存一个整型的引用计数器属性。对于一个对象,如果他没有在任何地方被引用,那么它的引用计数器为0,表示这个对象不再被使用,可进行回收。
- 优点:
1.实现简单,垃圾对象便于识别,判定效率高,回收没有延迟。 - 缺点:
1.需要单独的字段存储计数器,增加了存储空间的开销。
2.增加了时间开销,每次需要更新计数器。
3.无法处理循环引用的情况,导致java回收器中不使用这类算法。
可达性分析算法(标记阶段)
有效的解决引用计数算法中循环引用的问题,防止内存泄漏的发生。
1.如果要使用可达性分析算法来判断内存是否回收,那么分析工作必须在一个能保障一致性的快照中进行。
标记-清除算法(清除阶段)
1.当堆中的有效内存被耗尽的时候,就会停止整个程序,然后进行标记和清除的环节。
标记:从引用根节点开始遍历,标记所有的被引用的对象(非垃圾对象)。
清除:对堆内存进行从头到尾的线性遍历,没有标记可达对象则清除。
- 优点
容易理解。 - 缺点
1.效率不高。
2.进行Gc的时候需要停止整个的程序,导致用户体验比较差。
3.这种法师清理出来的内存是不连续的,会产生内存的碎片。
复制算法(清除 阶段)
为了解决标记清除算法在垃圾收集效率方面的缺陷。将活着的内存空间分为两块,每次使用其中的一块区域,在垃圾回收时候将正在使用的内存中的存活对象复制到未被使用的内存中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收。
- 优点
1.实现过程简单,运行高效。
2.保证内存的连续性,不会出现碎片化问题。 - 缺点
1.需要两倍的内存空间。
2.不管是内存占用或者时间开销也不小。
在新生代,使用复制算法进行回收。
分代收集算法
不同的对象声明周期是不一样的,不同生命周期的对象可以采取不同的收集方式,以提高回收效率。
目前所有的垃圾回收器都使用分代收集算法。
增量收集算法
垃圾收集线程只收集一小片区域的内存空间,接着切换到应用程序线程。依次反复,只到垃圾收集完成。
缺点:因为线程切换和上下文转换的消耗,会使得垃圾回收的总体成本上升,造成系统吞吐量的下降。