7

So what I am having here is a java program the manipulates a huge amount of data and store it into objects (Mainly hash-maps). At some point of the running time the data becomes useless and I need to discard so I can free up some memory.

My question is what would be the best behavior to discard these data to be garbage collected ?

I have tried the map.clear(), however this is not enough to clear the memory allocated by the map.

EDIT (To add alternatives I have tried)

I have also tried the system.gc() to force the garbage collector to run, however it did not help

Abdelrahman Shoman
  • 2,882
  • 7
  • 36
  • 61
  • 1
    Memory is not cleared then the objects become unreferenced. Garbage collection happens if your program needs more memory, it is unavailable and then the GC is started and reclaims all unreferenced objects. It is quite possible for some Java-programs that a GC is never happening in the runtime of the program, as no need for more memory was arising. – Mnementh Feb 09 '15 at 10:15
  • " this is not enough to clear the memory allocated by the map". How did you arrive at that conclusion? – Thilo Feb 09 '15 at 10:25

2 Answers2

12

HashMap#clear will throw all entries out of the HashMap, but it will not shrink it back to its initial capacity. That means you will have an empty backing array with (in your case, I guess) space for tens of thousands of entries.

If you do not intend to re-use the HashMap (with roughly the same amount of data), just throw away the whole HashMap instance (set it to null).

In addition to the above:

  • if the entries of the Map are still referenced by some other part of your system, they won't be garbage-collected even when they are removed from the Map (because they are needed elsewhere)
  • Garbage collections happens in the background, and only when it is required. So you may not immediately see a lot of memory being freed, and this may not be a problem.
Community
  • 1
  • 1
Thilo
  • 257,207
  • 101
  • 511
  • 656
  • 1
    Makes sense. Even leaked references of *entry instance* (if any) will not affect performance . +1 :) – TheLostMind Feb 09 '15 at 10:20
  • 1
    It follows, then, that if one uses a hashmap with a large number of entries, and later in the program it becomes smaller (few entries) but still used, it should probably be copied over to a new HashMap with a copy constructor rather than kept around. Right? – RealSkeptic Feb 09 '15 at 10:31
  • I don't know... Usually, programs have some kind of working memory requirement, freeing some memory that will be needed again a few minutes later does not seem like a big win. Even freeing memory that is never used again may not really benefit anyone. I would not worry about these things unless I am working with really huge collections. And if that is the case, maybe a more complete solution (such as off-heap storage) is called for anyway. – Thilo Feb 09 '15 at 11:02
9
 system.gc() 

is not recommended as jvm should be the only one to take care of all the garbage collection. Use Class WeakHashMap<K,V> in this case. The objects will automatically be removed if the key is no longer valid

Please read this link for reference

RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
shikjohari
  • 2,278
  • 11
  • 23
  • 3
    How do you know that a WeakHashMap is appropriate here? – Thilo Feb 09 '15 at 11:04
  • I am srprised... Why people have not upvoted this answer!?? I think WeakHashMap is perfect for such situations. isnt it?? Can someone please discuss on this?? – Manan Shah Jun 18 '16 at 09:08
  • @MananShah Well What if you need a hashmap with order so you should use LinkedHashMap you can't always use one sort of hashmap cause you might need the other anyway. – Steve Moretz Feb 12 '19 at 14:42