交叉引用造成内存丢失?动手试试吧

最近看了一些网上的文章各种详解、解剖Java GC,告诫我们要怎么避免内存丢失。我觉得很奇怪,.Net虚拟机已经多少年了,在虚拟机上解决回收交叉引用一直没问题,Java竟然要求开发人员来解决。一时兴起,动手试了一下。果然结果如我所预料,我不知道过去的JVM是什么样,现在的JVM应该是和.Net虚拟机一样先进了。


废话少说,直接上代码:

交叉引用:

public class Main {
    public static class A
    {
        public A(Object o)
        {
            this.obj = o;
        }

        public Object obj;
    }

    public static WeakReference GetWR()
    {
        A a1 = new A(null);
        A a2 = new A(a1);   // a2强引用a1
        a1.obj = a2;        // a1强引用a2
        return new WeakReference(a1);
    }

    public static void main(String[] args) {
        WeakReference wr = GetWR();

        do {
            if(wr.get() != null)
            {
                System.out.println("not gc");
                System.gc();
            }
            else
            {
                System.out.println("gc");
                break;
            }
        }while (true);
    }
}

输出结果:

not gc
gc

内部字段,强引用外部实例。举例来说,在Android中比较可能出现adapter中保存外部Activity的强引用:

public class Main {
    public static class A
    {
        public A(Object o)
        {
            this.obj = o;
        }

        public Object obj;
        public  Inner inn;

        public void Keep()
        {
            inn = new Inner(this);
        }

        private static class Inner
        {
            public A keeper;
            public Inner(A k)
            {
                keeper = k;
            }
        }
    }

    public static WeakReference GetWR()
    {
        A a1 = new A(null);
        a1.Keep();
        return new WeakReference(a1);
    }

    public static void main(String[] args) {
        WeakReference wr = GetWR();

        do {
            if(wr.get() != null)
            {
                System.out.println("not gc");
                System.gc();
            }
            else
            {
                System.out.println("gc");
                break;
            }
        }while (true);
    }
}

输出结果:


not gc
gc


结果很明显了,只要这个对象实例失去了被GC Root的强引用,就会被GC回收,这一点和.Net虚拟机是一样的。如果你使用GC Root去强引用不再需要的对象实例,也就怪不得所谓的“内存泄露”了。


除了查资料看书外,请多动动手。

你可能感兴趣的:(交叉引用造成内存丢失?动手试试吧)