我有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
实例。
如果一切正常,目前的情况没有任何问题。
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
实例?
答案 0 :(得分:0)
查看WeakRefernece
课程。听起来这就是你需要的。
简而言之,您将new WeakReference(foo)
存储在上下文中,而不仅仅是foo
,并相应地修改.get
(ref = context.get(id); foo = ref == null ? null : ref.get
)。
您还可以覆盖它上面的.enqueue
方法,以便在收集条目时从上下文中删除该条目。
基本上,这个想法是GC考虑的对象只是弱引用的,未使用的,并且会在下一个周期中收集它们。
这也将消除您自己的引用计数(a_gone_bar()
)的需要,GC会为您从上下文中删除条形图。