WeakHashMap or HashMap?
所以我有一连串的对象相互引用,它们来自ORM / Hibernate
-
大陆
-
有很多国家
-
有很多state
-
有很多城市
-
有很多城市
-
国家
-
有一个国家
-
有很多state
-
有很多城市
-
有很多城市
-
状态
-
城市
-
有一个大陆
-
有一个国家
-
有一个state
-
有很多城市
-
城市部分
-
有一个大陆
-
有一个国家
-
有一个state
-
有一个城市
对于某些方法,我需要能够进行一些快速查找以识别密钥。
因此,我目前在所有具有对象的对象中都有许多对象可以在内存中快速查找对象的ID,而不必在执行线程的生命周期内触发大量的数据库查询
1 2 3 4
| HashMap <Integer,Country > countriesTable
HashMap <Integer,State > statesTable
HashMap <Integer,City > citiesTable
HashMap <Integer,CityPart > citypartsTable |
但是我担心的是要保持循环引用,并且对象永远不会被垃圾回收清除,因为它们都通过ORM关系互相引用,并且它们都有指向eachohter的私有映射。
现在我已经阅读了有关WeakHashMap的内容,如果没有更强大的引用,它将清除引用。
问题是在我的情况下使用WeakHashMap是否可取,还是由Hashmap提供足够的服务,并且此设置和循环引用不会损害我的内存管理。
- 有什么方法可以更改设计以消除循环引用?
-
循环引用不会停止垃圾回收(尽管由于其他原因它们经常是个坏主意)。 WeakHashMap不是一个很好的缓存解决方案。在您可以证明进行数据库查找的"正确"解决方案不起作用之前,您不应该考虑缓存。
-
此外,由于您开始拥有这些结构,因此可以很好地使用同步工厂方法来获取实例,并让工厂方法在创建新实例之前检查实例是否已存在(因此,请确保每个实体都具有一个实例)。重要说明:过早的优化是99%邪恶的根源。
-
除此之外,Hibernate拥有自己的缓存解决方案,大多数现代JDBC驱动程序也是如此。很有可能您根本不需要为此担心。
-
如果循环引用会导致垃圾回收问题,那么ORM工具中的所有双向映射都将是即时内存泄漏。相信您使用的工具,不要相信您编写的未经测试的代码。
-
是的,但是hibernate只缓存索引键,但确实执行数据库查找。然后,它将模型重新初始化为新对象,如果我需要城市,state或其他地区的要素,则不得不一遍又一遍地重新查询已经存在的关系,而不是使用我已经初始化的对象。
-
@Gimby那就是我问这个问题的原因。我希望知道建立这些关系的最佳方法,因此我不必担心内存保持填充状态,因为参考循环本身就可以满足要求。从理论上讲,循环开始了一条路径,在该路径的末尾,将清除对主要对象的引用。当那一个被清除后,其余的也应该清除,因为他们做了自己的事情。我只需要知道hasmaps是否不会因为or??m映射而阻止发生这种情况
如果您有3个对象建立了一个隔离岛(A->B->C->A),但没有其他地方引用这些对象,则垃圾回收可以将它们全部扔掉而没有问题。
但是WeakHashMap在您的情况下无济于事,因为在WeakHashMap中,仅弱引用了键。 (来自WeakHashMap JavaDoc的第一句话是"具有弱键的Map接口基于哈希表的实现。")这些值仍然是硬引用。因此,WeakHashMap对您的情况无济于事。如果未从其他地方引用用作键的Integer对象,则e。 G。在对象内部,情况甚至更糟,因为它们才有资格进行垃圾回收并最终被丢弃。
如果没有在其他任何地方引用Integer对象,则需要一个普通的HashMap;如果这些对象是从对象内部引用的,则需要一个WeakHashMap,但还必须将值package在实例,然后从地图中检索对象时,请检查它们是否仍然可用或已被垃圾回收。
- 好吧,只要我保持孤立的小岛,我就应该好吗?
-
就像我说的,隔离岛可以被垃圾收集。但是,如果您在WeakHashMap中包含这些对象之一,则无法对其进行垃圾回收,因为存在对这些对象之一的硬引用,因此不再将它们隔离。
-
但是您也可以具有弱引用或软引用的普通哈希图。
-
是的,正如我在回答中所述,他可以。 ;-)