标记未准备好的对象以进行垃圾/完成参考(s)

时间:2014-12-07 15:03:05

标签: java garbage-collection

我有l:Map<Long,Foo>个foo对象。在我的应用程序上下文中,我创建Foo的实例太多,一些实例与多个线程堆栈共享 Foo

class Foo{
 public long id;
 public AtomicInteger ins;
 public Foo(long d,AtomicInteger i){id=d;ins=i;}
 public Foo(long d){id=d;ins=new AtomicInteger(1);}
}
//--
class Bar{
 Foo friend;
 public Bar(Foo f){friend=f;}
 //....some other properties
}

以下是获取Foo

的方法
public synchronized Bar a_bar_please(long id){
 Foo f=l.get(id);//no null allowed, Map implementation doesn't allow it
 if(f==null){f=new Foo();l.put(id,f);}
 else{f.ins.incrementAndGet();}
 return new Bar(f);
}

这是一种删除栏的方法

public synchronized void a_gone_bar(Bar b){
 if(b.friend.decrementAndget()==0){l.remove(b.friend.id);}
}

当没有任何Foo实例时,我删除{ready for GC)Bar实例。 如果一切正常,目前的情况没有任何问题。


案例研究:
现在假设10个线程调用id为{1}的方法,因此它意味着10个新的a_bar_please(id:long):Bar对象,所有实例都有Bar实例引用Foo。<登记/> 所以这里friend field实例有11个引用,10个来自Foo个实例,1个来自上下文Bar
现在我想删除l:Map实例当没有与之关联的ant Foo实例时,映射l 考虑8个持有Bar的线程加上它的共享Bar对象不会调用friend:Foo,因此上下文将保留a_gone_bar(b:Bar):void对象,因为Foo的最小数量为8,并且上下文永远不会删除它以标记GC 那么在这里,当地图中有引用时,如何标记ins实例?

1 个答案:

答案 0 :(得分:0)

查看WeakRefernece课程。听起来这就是你需要的。 简而言之,您将new WeakReference(foo)存储在上下文中,而不仅仅是foo,并相应地修改.getref = context.get(id); foo = ref == null ? null : ref.get)。 您还可以覆盖它上面的.enqueue方法,以便在收集条目时从上下文中删除该条目。

基本上,这个想法是GC考虑的对象只是弱引用的,未使用的,并且会在下一个周期中收集它们。

这也将消除您自己的引用计数(a_gone_bar())的需要,GC会为您从上下文中删除条形图。