1.GC的回收算法
**引用计数法**:每一个对象都有一个counter,只要有任何一个对象引用了该对象,则其counter加1,当引用失效时,counter减1,当counter为0时,对象不存在任何引用,在GC时被清除<br /> **标记清除法**:标记所有的存在引用的对象则未被标记的对象就是不存在引用的垃圾对象,GC会清除所有未被标记的对象<br /> **复制算法**:将内存空间分为两块相同的存储空间,每次只使用一块,GC时,将正在使用的内存中的存活对象复制到另一块存储空间中,然后清除正在使用的空间的所有对象<br /> **标记压缩法**:标记压缩法是对标记清除法的优化,所以也叫标记清除压缩法,先标记所有的可达对象(存在引用的对象),不同的是,标记完成后并不是直接清除未标记的垃圾对象,而是将所有的被标记的对象(即存活对象)压缩到内存空间的一端后在清理边界外所有的空间<br /> **分代算法**:将内存空间根据对象的特点不同进行划分,选择合适的垃圾回收算法,以提高垃圾回收的效率。<br /> **分区算法**:将整个堆空间划分为连续的不同小区间,每一个小区间都独立使用,独立回收。
2.Java的四种引用
1、强引用
最普遍的一种引用方式,如 String s = “abc”,变量 s 就是字符串“abc”的强引用,只要强引用存在,则垃圾回收器就不会回收这个对象。
*2、软引用(SoftReference)
用
于描述还有用但非必须的对象,如果内存足够,不回收,如果内存不足,则回收。一般用于实现内存敏感的高速缓存,软引用可以和引用队列 ReferenceQueue 联合使用,如果软引用的对象被垃圾回收,JVM 就会把这个软引用加入到与之关联的引用队列中。
3、弱引用(WeakReference)
弱引用和软引用大致相同,弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的 生命周期。在垃圾回收器线程扫描,一旦发现了只具有弱引用 的对象,不管当前内存空间足够,都会回收它的内存。
4、虚引用(PhantomReference)
虚引用并不会决定对象的生命周期。如果一个对象 仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。 虚引用主要用来跟踪对象被垃圾回收器回收的活动。
虚引用与软引用和弱引用的一个区别在于:
虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时, 如果发现它还有虚引,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
3.GC的堆的回收过程
首先GC内部有自己的算法,会不定期的对对象进行可达性分析,如果对象没有引用再指向这个对象了,那么根据GC自己的算法(标记清除整理法),标记对象,然后进行清除,最后在整理堆内存。相连时,相当于图论的从GC Roots不可达,则这个对象不可用。
4.GC如何判断对象是否回收
- 引用计数算法
在对象(对象头)中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一; 当引用失效时,计数器值就减一; 任何时刻计数器为零的对象就是不可能再被使用的。引用计数算法虽然占用了一些额外的内存空间来进行计数,但它的原理简单,判定效率也很高,在大多数情况下它都是一个不错的算法。这个看似简单的算法有很多例外情况要考虑,必须要配合大量额外处理才能保证正确地工作,譬如单纯的引用计数就很难解决对象之间相互循环引用的问题。
- 可达性分析算法
通过可达性分析算法来判定对象是否存活的。这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连,或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。