引用计数算法
<pre name="code" class="java">package test;
public class Demo {
private Object count = 0;
public static void main(String[] Args) {
new Demo().test();
}
private void test() {
Demo d1 = new Demo();
Demo d2 = new Demo();
d1.count = d2;
d2.count = d1;
d1 = null;
d2 = null;
System.gc();
}
}
上述就是一个典型的相互引用的例子,先说一个在安卓上的智能指针是如何解决的,它通过引入弱引用解决了这个问题,规定强引用计数为0时,不论弱引用是否为0都可以delete自己,在安卓中这个规则是可以调整的,这样虽然成功的解决了“死锁问题”,但是会有产生野指针的可能 ,比如d1强指针数为0了该 回收了,可是d2还持有它的弱引用,这里用这个指针来访问d1会产生严重的问题。安卓上因此有一个特别规定,弱指针先升级为强指针 ,才能访问它所指向的目标对象 。可能会有人问,java不是没有指针么。。java是没有。是因为jvm已经把指针的问题解决了,我们这里讲的是jvm和android系统。
可达性分析算法
这个算法的基本思想是通过 叫做GC Roots的对象作为起始点,从这些节点 向下搜索,搜索走过的路径叫做引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可引用的。在java C#包括古老的Lisp语言中都是用这个方法判断对象是否存活的。
java中可做为GC Roots的对象 :
虚拟机栈中引用的对象
方法 区中类静态发生引用的对象
方法区中常量 引用 的对象
本地方法栈中JNI引用的对象
java中的各种引用
由强到弱依次分为:
强引用
软引用
弱引用
虚引用
曾经还用到过,因为开发一个安卓app,里面有一个功能是播放 gif图,图的解码器是用的一个开源的项目 ,但这个项目存在 一个问题就是经常会oom(outofmemory),自己还改良一下,就是通过引用软引用和弱引用,希望能加大垃圾收集器的回收力度。结果效果并不好。。那么接着说这四个引用的强度区别
强引用就是我们通常用的new
软引用就是在要发生oom之前进行回收
弱引用就算内存够用也会被回收
虚引用唯一的作用就是在回收的时候收到一个系统 通知 。
这里我写了一个测试类
package test;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
public class Demo {
private String name;
public Demo(String name) {
super();
this.name = name;
}
public Demo() {
super();
}
public static void main(String[] Args) {
new Demo().test();
System.gc();
}
@Override
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
super.finalize();
System.out.println("我死啦我死啦" + this.name);
}
void test() {
Demo a = new Demo("soft");
SoftReference<Demo> d1 = new SoftReference<Demo>(a);
Demo b = new Demo("weak");
WeakReference<Demo> d2 = new WeakReference<Demo>(b);
Demo c = new Demo("pham");
ReferenceQueue<Demo> temp = new ReferenceQueue<Demo>();
PhantomReference<Demo> d3 = new PhantomReference<Demo>(c, temp);
}
}
运行结果几次各有不同:
结果 1:
我死啦我死啦pham
我死啦我死啦weak
我死啦我死啦soft
我死啦我死啦null
结果2:
我死啦我死啦pham
结果3:
我死啦我死啦pham
我死啦我死啦weak
这里可以看出虚引用的确是一点活路都没有,而且垃圾回收也的确是不确定 的。不过总的强度没有错误 ,是从弱到强进行回收的
垃圾收集算法
标记-清除算法
算法如其名,就是先标记出哪个是需要回收的,然后再进行回收,不过有一个严重的问题,现在我们想象内存是一个棋盘,然后被标记的是几个块,现在就是可用的内存和要回收和内存块是相间的,跟熊猫是的。回收过后就会产生好多好内存碎片,以至于以后要分配较大的内存的时候 找不到地方。
复制算法
它将可用内存分成的两大块,每次只使用其中一块,当这一块用完了,就将存活的对象复制到另一块上去,然后那块就完全被 清理干净 ,典型的用空间换时间的算法,这虽然效率高,但是未免也太费内存了。
标记-整理算法
分代收集算法