Java垃圾回收
在学习Java的过程中,我们都知道了“Java会拾荒”,即垃圾回收:
创建对象时,它会被存放在称为堆的内存区域,不管对象是如何创建的都会放在此区域中;
此区域并非不同的堆;它是可以回收垃圾的堆(Garbage-Collectible Heap);
Java会根据对象的大小来分配内存空间;
Java会主动帮你管理内存;当某个对象被虚拟机察觉不再被使用,该对象就会被标记为可回收的;
如果内存开始不足,垃圾收集器就会启动来清理垃圾、回收控件,让空间能够被再次利用;
回收机制
某个对象被虚拟机察觉不再被使用的方式有两种:
实际就是判断对象是否是垃圾的算法;
1-引用计数算法:
堆中每个对象都有一个引用计数器;每有一个对象的引用,相应的引用计数+1(相反的情况则-1);
任何引用计数为0的对象可以被当做垃圾进行收集;
优点:执行简单、判断高效;
缺点:难以检测出对象之间的循环引用;
2.根搜索算法:(现在大多数JVM使用的算法)
根集(Root Set):正在执行的Java程序可以访问的引用变量的集合(注意不是对象的集合);
通过一些列的GC Roots对象作为起始点,寻找其他节点,找到之后继续向下寻找其他节点;
搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链连接时,则此对象不可用;
关于JVM:
在目前发布的Java8中,默认的虚拟机使用的是HotSpot(另一种是JRockit),对应的垃圾回收机制也就是HotSpot的GC机制;
而JVM HotSpot使用的就是可达性分析法,即根搜索算法;
循环引用实践
在学习设计模式的过程中,在观察者模式以及正在学习的状态模式,都使用了类似循环引用的方式,具体实现如下:
一种是比较经典的产生循环引用的场景;
另一种是设计模式书中经常使用的场景;
总结
我们看到:
在将引用置null之后,主动调用垃圾回收,两个对象会调用各自的finalize()方法;
这正与我们前文所述的根搜索算法相对应,被标记为可回收的对象,之后顺利的被垃圾收集器清理掉了;