Mic*_*udy 25 java anonymous-inner-class anonymous-class cyclic-reference
我有以下代码片段:
public class Example {
private Integer threshold;
private Map<String, Progress> history;
protected void activate(ComponentContext ctx) {
this.history = Collections.synchronizedMap(new LinkedHashMap<String, Progress>() {
@Override
protected boolean removeEldestEntry(Map.Entry<String, Progress> entry) {
return size() > threshold;
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
Theres是匿名LinkedHashMap类和Example类之间的循环依赖.这样可以吗?为什么不?它会被垃圾收集器很好地收回吗?
aio*_*obe 22
这样可以吗?
这完全没问题.
threshold是一个字段,因此可以在匿名类中引用它而没有任何问题.(如果threshold是局部变量,则必须(有效)最终.)
类之间的循环依赖是常见的,当依赖图很小时(如本例所示),它不会造成任何问题.你LinkedHashMap是一个匿名课的事实并不重要.
它会被垃圾收集器很好地收回吗?
关于内存泄漏+内部类的唯一警惕是(非静态)内部类具有对其封闭对象的隐式引用.这意味着如果您创建了大量内部类的实例,则不能指望外部类对象的实例被垃圾回收.
在这种情况下,这意味着如果您泄漏对history地图的引用,Example则不会对GC进行实例化.
相关说明:
考虑到你正在使用synchronizedMap它似乎你正在研究一个多线程程序.如果是这种情况,您需要对该threshold字段的同步和可见性问题保持警惕.
如果可能的话,尽量让threshold场地最终
另一种选择是为您创建一个命名类,LinkedHashMap并将其threshold作为该类中的字段包含在内.
无论如何,你都有这种依赖,因为匿名内部类的每个对象都隐含了对封闭类对象的引用.Java是这样设计的,嵌套的内部类有这个参考是有原因的,所以从语言规范的角度来看,这会编译并看起来非常正常.
关于(缺少)"设计气味",如果这个匿名类对象完全封装在Example类中,没有独特的意义没有它的封闭上下文,并且不会泄露到Example类之外的任何地方,那么引用封闭字段没有任何问题类.您只需使用此内部类来组合一些逻辑.
但是,如果此对象从封闭对象中泄漏(例如,通过getter返回),则应禁止此操作或将其重构为threshold作为参数接收的静态内部类.此内部对象保存对封闭对象的引用,并可能使其远离GC,从而导致内存泄漏.
| 归档时间: |
|
| 查看次数: |
1689 次 |
| 最近记录: |