I have an application which takes data from a file and stores it for later use. Each line in the file corresponds to one object Foo, which contains n pairs of Bar objects which are made of a single character String, each with a distinct Name. So I store this data like so:
Foo extends HashMap<Name, Pair<Bar, Bar>>
where Pair<A, B> is my own class which just stores 2 values and provides some methods (equals, hashcode etc).
The problem I have encountered is that when I store n=114 (this just happens to be the number in my test data) Pair objects in my Foo it should have a retained size of not much more than 228 bytes, when in fact it is more like 25kbytes. This means when I have ~1000 Foo objects I need 25MB of memory rather than 228kB, which is not really acceptable. (Note: the keys for each Foo object are the same, fooOne.keySet().equals(fooTwo.keySet()))
I am using VisualVM to profile my application, and when I delve into an instance of Foo I see:
Field Type Retained
-
this Foo 24750
...
v table HashMap$Entry[] 24662
v [0] HashMap$Entry 200
v value Pair 156
v first Bar 60
...
> code String 36
v second Bar 60
...
> code String 36
v key Name 72
...
> name String 36
> [1] HashMap$Entry 200
> [2] <HashMap$Entry> -
...
> [233] HashMap$Entry 600
...
> [255] <HashMap$Entry> -
So as you can see all the useful information is being surrounded by lots of useless (to me) data. If I had fewer, larger objects with the same data in I can see my useful:useless ratio would be better, but I can’t see how I can implement this in any other way. Is there some other way I can store my data, but still be as convenient and easy to use as this?
EDIT
My application will need to be scalable to upwards of 6000 Bar instances and maybe as many Foo instances.
I’m not entirely sure that I get your question right but in this situation using Flyweights may do the trick.
Flyweight pattern