2

So I have a chain of objects that reference each other from ORM / Hibernate

  • Continent
    • has many countries
    • has many states
    • has many cities
    • has many cityparts
  • Country
    • has one Country
    • has many states
    • has many cities
    • has many cityparts
  • State
    • has one Continent
    • has one Country
    • has many cities
    • has many cityparts
  • City
    • has one Continent
    • has one Country
    • has one State
    • has many cityparts
  • City part
    • has one Continent
    • has one Country
    • has one State
    • has one City

For some methods i need to be able to do some quick lookups for identifying keys.

So for that I currently have in all the objects that have Many to be able to do quick lookups of the Id's of the object in memory without having to fire off a gazillion database queries in the lifetime of the execution thread

HashMap<Integer,Country>     countriesTable
HashMap<Integer,State>       statesTable
HashMap<Integer,City>        citiesTable
HashMap<Integer,CityPart>    citypartsTable

But what i'm worried about is cyclic references being held and the objects never getting cleared by garbage collection because they all reference eachother through the ORM relations and they all have private maps pointing to eachohter

Now I have read about WeakHashMap that it will clear the references if there are no more strong references.

The question is Is it adviceable to use WeakHashMap in my situation or am I enough served by Hashmap and this setup and cyclic references will not impair my memory management.

Tschallacka
  • 27,901
  • 14
  • 88
  • 133
  • 1
    Is there any way you can change your design to eliminate cyclic references? – Paul Boddington Apr 12 '16 at 13:24
  • 2
    Cyclic references don't stop garbage collection (although they are often a bad idea for other reasons). WeakHashMap isn't a good caching solution. You shouldn't think about caching until you can prove that the "correct" solution of doing database lookups doesn't work. – biziclop Apr 12 '16 at 13:24
  • Additionally, since you start having those structures, you may very well use a synchronized factory method to get the instances, and have the factory method check if the instances already exist before creating new ones (so you ensure a single instance for each entity). IMPORTANT: Premature optimization is the root of 99% of evil. – SJuan76 Apr 12 '16 at 13:27
  • 1
    Further to that, Hibernate has its own caching solution, and so do most modern JDBC drivers. Chances are that you really don't need to worry about this at all. – biziclop Apr 12 '16 at 13:27
  • 1
    If cyclic references would cause garbage collection problems then all bidirectional mappings in ORM tooling would be instant memory leaks. Trust the tools you use, distrust the untested code you write. – Gimby Apr 12 '16 at 13:28
  • yea, but hibernate only caches the index keys but does perform a database lookup. It then reinitalises the models as new objects, forcing me to reQuery already existing relations over and over if I need continets from a city or a state or something, instead of using the object I already have initalised. – Tschallacka Apr 12 '16 at 13:29
  • @Gimby Thats the reason i ask this question. I wish to know the best way to set up these relations so i dont have to worry about the memory stayin filled because the reference loop is feeding itself. In theory the loop starts a path, at at the end of the path the references to the main object are cleared. When that one is cleared the rest should be cleared too because they did their thing. I just need to know if the hasmaps will not prevent that from happening because of the orm mappings – Tschallacka Apr 12 '16 at 13:32

1 Answers1

3

If you have 3 objects that build an isle of isolation (A->B->C->A) and none of these is referenced from anywhere else, garbage collection can throw all of them away without problem.

But a WeakHashMap will not help in your situation, as in a WeakHashMap only the keys are referenced weakly. (First sentence from WeakHashMap JavaDoc is "Hash table based implementation of the Map interface, with weak keys.") The values are still hard references. So a WeakHashMap will not help you in your case. If the Integer objects used as keys are not referenced from somewhere else, e. g. from within the objects it is even worse, as then they are eligible for garbage collection and thrown aways eventually.

What you would need is a normal HashMap if your Integer objects are not referenced anywhere else, or a WeakHashMap if those objects are the ones referenced from within your objects but you also have to wrap the values in WeakReference instances and then when retrieving your objects from your map check whether they are still available or got garbage collected.

Vampire
  • 35,631
  • 4
  • 76
  • 102
  • Okay, so as long as i maintain the isle of isolation I should be good? – Tschallacka Apr 12 '16 at 13:35
  • 1
    As I said, Isle of Isolation can be garbage collected. But if you have one of those objects in a `WeakHashMap`, they can **not** be garbage collected, as then there is a hard reference to one of those objects and thus they are not isolated anymore. – Vampire Apr 12 '16 at 13:39
  • 1
    But you can also have a normal hashmap of weak or soft references. – biziclop Apr 12 '16 at 13:44
  • 1
    Yes he can, just as I described in my answer. ;-) – Vampire Apr 12 '16 at 13:49