Java中强引用或弱引用可访问的对象

Java中强引用或弱引用可访问的对象,java,weak-references,strong-references,Java,Weak References,Strong References,我正在与垃圾收集器搏斗。我想列出从某个对象可以强或弱访问的所有对象。我知道我需要递归地去做,但是我找不到一个简单的方法来实现它。你能帮帮我吗 public static List<Object> getAllReachableObjects (Object from) 公共静态列表getAllReachableObjects(对象来自) 严格的解决方案不应该如此困难,但是。。。请注意,从给定对象可以访问的对象可能有很多 根据评论进行编辑: 对象应分为软对象、弱对象、幻象对象和强可达

我正在与垃圾收集器搏斗。我想列出从某个对象可以强或弱访问的所有对象。我知道我需要递归地去做,但是我找不到一个简单的方法来实现它。你能帮帮我吗

public static List<Object> getAllReachableObjects (Object from)
公共静态列表getAllReachableObjects(对象来自)

严格的解决方案不应该如此困难,但是。。。请注意,从给定对象可以访问的对象可能有很多

根据评论进行编辑:

对象应分为软对象、弱对象、幻象对象和强可达对象。这有点复杂。可以手动实现基于图形的优雅解决方案,但我实际修改了第一个答案中的代码。请注意,这尚未经过广泛测试

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class AllReachableObjects
{
    public static void main(String[] args)
    {
        TestObject a = new TestObject("a", null, null, null, null);
        TestObject as = new TestObject("as", a, null, null, null);
        TestObject aw = new TestObject("aw", null, a, null, null);
        TestObject ap = new TestObject("ap", null, null, a, null);
        TestObject ar = new TestObject("ar", null, null, null, a);

        printInfo(new ReachableObjects(as));
        printInfo(new ReachableObjects(aw));
        printInfo(new ReachableObjects(ap));
        printInfo(new ReachableObjects(ar));

        TestObject asr = new TestObject("as", null, null, null, as);
        TestObject ars = new TestObject("as", ar, null, null, null);

        printInfo(new ReachableObjects(asr));
        printInfo(new ReachableObjects(ars));

    }

    private static void printInfo(ReachableObjects r)
    {
        System.out.println("Soft");
        printList(r.getSoftlyReachable());
        System.out.println("Weak");
        printList(r.getWeaklyReachable());
        System.out.println("Phantom");
        printList(r.getPhantomReachable());
        System.out.println("Strong");
        printList(r.getStronglyReachable());
    }

    private static void printList(List<Object> list)
    {
        for (Object object : list)
        {
            System.out.println("    "+object+" (class "+object.getClass()+")");
        }
    }


}


class ReachableObjects
{
    private static final Field REFERENCE_REFERENT_FIELD =
        initReferenceReferentField();

    private static Field initReferenceReferentField()
    {
        try
        {
            return Reference.class.getDeclaredField("referent");
        }
        catch (NoSuchFieldException e)
        {
            e.printStackTrace();
        }
        catch (SecurityException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    private Set<Object> softlyReachable;
    private Set<Object> weaklyReachable;
    private Set<Object> phantomReachable;
    private Set<Object> stronglyReachable;


    public ReachableObjects(Object object)
    {
        softlyReachable = new LinkedHashSet<Object>();
        weaklyReachable = new LinkedHashSet<Object>();
        phantomReachable = new LinkedHashSet<Object>();
        stronglyReachable = new LinkedHashSet<Object>();

        try
        {
            collectAllReachableObjects(object, stronglyReachable, "");
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
        softlyReachable.removeAll(weaklyReachable);
        softlyReachable.removeAll(phantomReachable);
        softlyReachable.removeAll(stronglyReachable);

        weaklyReachable.removeAll(softlyReachable);
        weaklyReachable.removeAll(phantomReachable);
        weaklyReachable.removeAll(stronglyReachable);

        phantomReachable.removeAll(softlyReachable);
        phantomReachable.removeAll(weaklyReachable);
        phantomReachable.removeAll(stronglyReachable);
    }

    private void collectAllReachableObjects(
        Object from, Set<Object> result, String indent) 
        throws IllegalArgumentException, IllegalAccessException
    {
        if (result.contains(from))
        {
            return;
        }
        result.add(from);
        Class<?> c = from.getClass();
        Class<?> leafClass = c;
        while (c != null)
        {
            //System.out.println(indent+"Class "+c);

            Field fields[] = c.getDeclaredFields();
            for (Field field : fields)
            {
                //System.out.println(indent+"Field "+field+" of "+c);

                if (Modifier.isStatic(field.getModifiers()))
                {
                    continue;
                }

                boolean wasAccessible = field.isAccessible();
                field.setAccessible(true);
                Object value = field.get(from);
                if (value != null)
                {
                    Set<Object> nextResult = stronglyReachable;
                    if (field.equals(REFERENCE_REFERENT_FIELD))
                    {
                        if (leafClass.equals(SoftReference.class))
                        {
                            nextResult = softlyReachable;
                        }
                        else if (leafClass.equals(WeakReference.class))
                        {
                            nextResult = weaklyReachable;
                        }
                        else if (leafClass.equals(PhantomReference.class))
                        {
                            nextResult = phantomReachable;
                        }
                    }
                    collectAllReachableObjects(value, nextResult, indent+"  ");
                }
                field.setAccessible(wasAccessible);
            }
            c = c.getSuperclass();
        }
    }

    List<Object> getSoftlyReachable()
    {
        return new ArrayList<Object>(softlyReachable);
    }
    List<Object> getWeaklyReachable()
    {
        return new ArrayList<Object>(weaklyReachable);
    }
    List<Object> getPhantomReachable()
    {
        return new ArrayList<Object>(phantomReachable);
    }
    List<Object> getStronglyReachable()
    {
        return new ArrayList<Object>(stronglyReachable);
    }
}


class TestObject
{
    String name;
    SoftReference<TestObject> softReference;
    WeakReference<TestObject> weakReference;
    PhantomReference<TestObject> phantomReference;
    Object strongReference;

    TestObject(String name, 
        TestObject soft, TestObject weak, TestObject phantom, TestObject strong)
    {
        this.name = name;
        if (soft != null)
        {
            softReference = new SoftReference<TestObject>(soft);
        }
        if (weak != null)
        {
            weakReference = new WeakReference<TestObject>(weak);
        }
        if (phantom != null)
        {
            phantomReference = new PhantomReference<TestObject>(phantom, new ReferenceQueue<>());
        }
        strongReference = strong;
    }
    @Override
    public String toString()
    {
        return name;
    }
}
import java.lang.ref.PhantomReference;
导入java.lang.ref.Reference;
导入java.lang.ref.ReferenceQueue;
导入java.lang.ref.SoftReference;
导入java.lang.ref.WeakReference;
导入java.lang.reflect.Field;
导入java.lang.reflect.Modifier;
导入java.util.ArrayList;
导入java.util.LinkedHashSet;
导入java.util.List;
导入java.util.Set;
公共类Allreachable对象
{
公共静态void main(字符串[]args)
{
TestObject a=新的TestObject(“a”,null,null,null,null);
TestObject as=新的TestObject(“as”,a,null,null,null);
TestObject aw=新的TestObject(“aw”,null,a,null,null);
TestObject ap=新的TestObject(“ap”,null,null,a,null);
TestObject ar=新的TestObject(“ar”,null,null,null,a);
printInfo(新的可访问对象(as));
printInfo(新可到达对象(aw));
printInfo(新可达对象(ap));
printInfo(新的可达对象(ar));
TestObject asr=新的TestObject(“as”,null,null,null,as);
TestObject ars=新的TestObject(“as”,ar,null,null);
printInfo(新可达对象(asr));
printInfo(新可达对象(ars));
}
私有静态void printInfo(可访问对象)
{
System.out.println(“软”);
printList(r.getSoftlyReachable());
System.out.println(“弱”);
打印列表(r.getWeaklyReachable());
系统输出打印项次(“幻影”);
打印列表(r.getPhantomReachable());
System.out.println(“强”);
打印列表(r.getStronglyReachable());
}
私有静态无效打印列表(列表)
{
用于(对象:列表)
{
System.out.println(“+object+”(class“+object.getClass()+”);
}
}
}
类可到达对象
{
私有静态最终字段引用\引用\字段=
initReferenceReferentField();
私有静态字段initReferenceReferentField()
{
尝试
{
返回Reference.class.getDeclaredField(“referent”);
}
捕获(无此字段例外)
{
e、 printStackTrace();
}
捕获(安全异常e)
{
e、 printStackTrace();
}
返回null;
}
专用集软交换;
私有集易受攻击;
私有集幻影可达;
私有集强可访问;
公共可访问对象(对象)
{
softlyReachable=newlinkedhashset();
weaklyReachable=newlinkedhashset();
phantomReachable=newlinkedhashset();
stronglyReachable=newlinkedhashset();
尝试
{
CollectAllReachable对象(对象,stronglyReachable,“”);
}
捕获(IllegalArgumentException e)
{
e、 printStackTrace();
}
捕获(非法访问例外e)
{
e、 printStackTrace();
}
软可拆卸。移除所有(软可拆卸);
软性可触及。可移除所有(可触及幻影);
SoftlyReactable.removeAll(StronglyReactable);
弱可拆卸。移除所有(软可拆卸);
移除所有(幽灵可达);
weaklyReachable.removeAll(stronglyReachable);
幻影可达。移除所有(软可触及);
幻影可达。移除所有(脆弱的可达);
幻影可到达。移除所有(强可到达);
}
私有void CollectAllAccessible对象(
对象来源、设置结果、字符串缩进)
抛出IllegalArgumentException,IllegalAccessException
{
if(result.contains(from))
{
返回;
}
结果。添加(从);
c类=from.getClass();
类别=c;
while(c!=null)
{
//系统输出打印项次(缩进+“类”+c);
字段字段[]=c.getDeclaredFields();
用于(字段:字段)
{
//系统输出打印项次(缩进+字段+字段+字段+c);
if(Modifier.isStatic(field.getModifiers()))
{
继续;
}
布尔值wasaccessable=field.isAccessible();
字段。setAccessible(true);
对象值=field.get(from);
if(值!=null)
{
设置nextResult=stronglyReachable;
if(field.equals(REFERENCE\u REFERENT\u field))
{
if(leafClass.equals(SoftReference.class))
{
nextResult=可软更换;
}
else if(leafClass.equals(WeakReference.class))
{
nextResult=弱可回收性;
}
else if(leafClass.equals(PhantomReference.class))
{
nextResult=幻影可达;
}
}
CollectAllReach对象(值、nextResult、i
   public static List < Object > getStronglyReachable (Object from)
     // contains all objects that are ONLY strongly reachable

   public static List < Object > getSoftlyReachable (Object from)
     // contains all objects that are strongly OR softly reachable

   public static List < Object > getWeaklyReachable (Object from)
     // contains all objects that are strongly OR softly OR weakly reachable
// if an object is an array, iterate over its elements
if (from.getClass ().isArray ())
    for (int i = 0; i < Array.getLength (from); i++)
        collectAllReachableObjects (Array.get (from, i), result);