你凭什么说我是垃圾对象??
Java对象小明:你凭什么说我是垃圾?
Java虚拟机:那我就给你说道说道!!!
判断对象是否是垃圾,有两种方法:
-
引用计数
对象每被引用一次,计数就加1,当计数为0的时候,说明没有被引用,也就是垃圾对象,可以被回收了。
Java对象小明:那如果我和Java对象小刚手牵手互相引用是不是就可以天长地久永远不被回收了呢?
Java虚拟机:别着急,第二种方法可以让你显出原形,现形吧,渣男。
-
可达性分析
JVM规定了四种GCRoots对象,只要是这四种GCRoots对象引用链上的对象,都是暖男(可用对象),反之都是垃圾,渣男,狗东西,就需要被回收。
Java对象小明:这么狠?没有被原谅的机会吗?
Java虚拟机:人非圣贤,孰能无过,就给你一次机会吧。
finalize方法
在虚拟机中,要宣告一个对象的死亡,至少要经历两次标记过程,第一次进行可达性分析后,发现你没有在任何一个GCRoots的引用链上,疑似渣男,黄牌警告,然后再进行第二次的筛选,看你是否有必要执行finalize方法,假如你根本没有给自己留后路(没有覆盖finalize方法),或者之前已经给过你机会(之前已经被调用过finalize方法),那么虚拟机将这两种情况视为“没必要执行”,去死吧渣男。
Java对象小明:扯了这么多,这引用到底是啥?
Java虚拟机:这么说吧,Java将引用分为四种,就像你和妹子的四种关系。
强引用:如果你是妹子官宣的男友,那你俩的关系就像这强引用一样,只要这关系还在,你就不会被叫渣男,也就是这个对象只要用和GCRoots引用链保持着强引用的关系,就不会被回收。
软引用:如果你和妹子的关系类似于软引用,恭喜你,你就是那几十个备胎中的一个,有事先找你,没事就踢一边,也就是有你没你一个样。在妹子感觉快瞒不住她男朋友的时候,也就是你俩over的时候。也就是当系统内存快满的时候,才回去回收软引用关联的对象。Java提供了SoftReference类来实现软引用。
弱引用:弱引用和软引用差不过,也是非必须的对象,被弱引用关联的对象只能生存到下次垃圾回收。也就是你的新鲜感一过,你就被妹子移除了好友列表。
虚引用:它是最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会堆其生存时间造成影响。它的作用只是为了能在这个对象被回收的时候收到一个系统通知。也就是妹子和你联系,只是为了听你分手的故事。
周大神的深入理解Java虚拟机中关于软引用的例子:
public class GCTest { public static GCTest Save_Hook = null; public void isalive(){ System.out.println("我还活着!"); } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("执行 finalize 方法"); GCTest.Save_Hook = this; } public static void main(String[] args) throws InterruptedException { Save_Hook = new GCTest(); //将new GCRoots()的引用去除 Save_Hook = null; System.gc(); Thread.sleep(5000); if (Save_Hook != null){ Save_Hook.isalive(); }else { System.out.println("game over!!"); } //下面第二次自救失败 Save_Hook = null; System.gc(); Thread.sleep(5000); if (Save_Hook != null){ Save_Hook.isalive(); }else { System.out.println("game over!!"); } } }
结果
执行 finalize 方法 我还活着! game over!!