【发布时间】:2017-09-15 02:04:22
【问题描述】:
我遇到了一段我确信会导致意外内存泄漏的代码:
Object user = getUser("Bob");
Map<String, WeakReference<Object>> map = new HashMap<>();
map.put("Bob", new WeakReference( user ) );
此映射的目的是缓存对象,并在它们不再被强引用时由 GC 从映射中自动清除。
但是,我看到的方式是,如果键也不是弱引用,那么一旦对象被 GC'ed,哈希映射中仍然会有一个键指向 null 的条目。因此,地图仍将包含相同数量的行,只是都指向空值。
所以在上面的例子中,一旦对user的所有强引用被释放,并且GC销毁Object,映射中的条目将相当于:
map.put("Bob", null );
因此,除非有一个清理例程来刷新所有具有空值的键,否则我的地图将继续增长。
那么问题就变成了如何解决这个问题?是否有一个我可以使用的地图构造,如果值被破坏,它会自动刷新我的条目?
我打算做类似的事情:
Object user = getUser("Bob");
Map<String, WeakReference<Object>> map = new WeakHashMap<>();
map.put(user.getUsername(), new WeakReference( user ) );
但这似乎是一个非常有限的用例,我的密钥必须是从我的值中检索的对象。使用WeakHashMap,我的键不能是字符串常量(即:“Bob”),否则不会有任何其他对它的引用,GC 将从我的地图中清除该对象。
是否有其他缓存结构可以提供所有这些功能?
【问题讨论】:
标签: java memory-leaks garbage-collection weak-references