1. 什么是garbage垃圾?
没有任何引用指向的一个对象或者多个对象(循环引用),就是垃圾
1.1 Java与C++对于垃圾处理的区别
- Java
GC处理垃圾
开发效率高,执行效率低 - C++
手动处理垃圾
忘记回收 -> 会导致内存泄漏
回收多次 -> 会造成非法访问
开发效率低,执行效率高
2. 怎么定位垃圾
Java堆中存放着几乎所有的对象实例,垃圾回收器在堆进行垃圾回收前,首先要判断这些对象那些还存活,哪些成为了”垃圾“。定位“垃圾”有如下算法:
(1)引用计数法(ReferenceCount)
(2)根可达算法(RootSearching)
2.1 引用计数法(ReferenceCount)
引用计数法描述的算法为:给对象增加一个引用计数器,每当有一个地方引用它时,计数器就+1;当引用失效时,计数器就-1;任何时刻计数器为0的对象就是不能再被使用的,成为“垃圾”。
引用计数法实现简单,判定效率也比较高,在大部分情况下都是一个比较好的算法。比如Python语言就是采用的引用计数法来进行内存管理的。
但是,在主流的JVM中没有选用引用计数法来管理内存,最主要的原因是 引用计数法无法解决对象的循环引用问题。
2.2 根可达算法(RootSearching)
Java并不采用引用计数法来判断对象是否已成为“垃圾”,而采用“根可达算法”来判断对象是否存活(同样采用此法的还有C#、Lisp-最早的一门采用动态内存分配的语言)。
此算法的核心思想:通过一系列称为“GC roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为“引用链”,当一个对象到 GC roots 没有任何的引用链