110

I have a Map as syntax as Map<String, String> testMap = new HashMap<String, String>();. In this map there can be 1000 data.

When my application requires to new list of data, then I must clear the Map. But when I saw the code of Map.clear() as

/**
     * Removes all of the mappings from this map.
     * The map will be empty after this call returns.
     */
    public void clear() {
        modCount++;
        Entry[] tab = table;
        for (int i = 0; i < tab.length; i++)
            tab[i] = null;
        size = 0;
    }

I realize that clear method goes in loop for n times (Where n is number of data in Map). So I thought there can be a way to redefine that Map as testMap = new HashMap<String, String>(); and previously used Map will be Garbage collected.

But I am not sure this will be a good way. I am working on mobile application.

Can you please guide me?

Kevin
  • 11,521
  • 22
  • 81
  • 103
Pankaj Kumar
  • 81,967
  • 29
  • 167
  • 186
  • 3
    Long time ago since this question was posted, but anyway, Google continues to guide us to it. So just another advantage of using clear over new. You will be able to declare the map as final and so the compiler will be able to detect programming bugs for free. For other type of structures "final" will also remove the burden of allocating new memory making our code (much) faster. – earizon Jul 26 '17 at 09:29
  • Even longer ago now! Still found it. I'm looking at this question from a concurrency PoV. My singleton class is multi-threaded, and want to make sure when I "clear" the Map that it doesn't take too long and cause a concurrency modification exception. So I think best for me is to define a new one, and if another thread is accessing the Map at that moment, it will use the old reference, and the next time would be on the new empty one. – Aaron Jul 21 '23 at 20:26

7 Answers7

124

Complicated question. Let's see what happens.

You instantiate a new instance, which is backed with new array. So, garbage collector should clear all the key and values from the previous map, and clear the reference to itself. So O(n) algorithm is executed anyway, but in the garbage collector thread. For 1000 records you won't see any difference. BUT. The performance guide tells you that it is always better not to create new objects, if you can. So I would go with clear() method.

Anyway, try both variants and try to measure. Always measure!

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
33

When you say Map.clear() on a Map of size n... You are asking the GC to clean up 2*n (Key & Value) objects. When you say null to the same Map, you are asking the GC to clean up 2*n+1 (1 for the Map itself) objects. Then you will have to create a new Map instance yet another overhead. So go for Map.clear(). You will be wise to preset the size of the Map while instantiating it.

agf
  • 171,228
  • 44
  • 289
  • 238
Tanveer
  • 355
  • 2
  • 2
  • 3
    The big O estimates you give only apply if the keys and values in the Map are not referenced anywhere else. If any keys and values are referenced somewhere else in the application then they will not be garbage collected. Perhaps I'm mistaken if by "clean up" you mean the garbage collector must check the object to see if it needs garbage collecting. There's another point here... the garbage collector may _never_ clean up the objects even if there is no reference to them: http://stackoverflow.com/a/2506525/361855 . My point is that you cannot estimate the cost of GC when changing the map ref. – Jason May 22 '15 at 16:01
  • I don't believe that is how this will go down. GC doesn't immediately spring into action. It will do so when the work load is lesser/there is memory reorg going on. – navderm Aug 02 '23 at 15:15
12

I thought Creating object in java more expensive in terms of memory,so it is better to you go with .clear(),so you are using same object instead of creating new one

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
sunriser
  • 770
  • 3
  • 12
6

The idea of having clear() method is to remove references to other objects from the map, so that the key/values are not held up from gcing if the "map is referenced somewhere else".

But if your map is a local map only used by your specific code( i.e. "map is 'not' referenced somewhere else") then go ahead and use a new map instead, but setting a 1000 references to null wont be a big performance hit anyway.

Suraj Chandran
  • 24,433
  • 12
  • 63
  • 94
  • 1
    Yes This wont be a big performance hit for 1000 references. I was asking about if creating a new instance is better than clear method or not. And is there any drawback to use new instance? – Pankaj Kumar Jul 20 '11 at 06:46
  • 1
    The main drawback would be that with new, your old HashMap is still in memory until the garbage collector releases it. It will add a small memory overhead of memory and a little more processing overhead for the GC to release it. In any case, the differences of either option (reusin or creating new) will be negligible (unless all your app does is creating HashMaps) – SJuan76 Jul 20 '11 at 07:04
4

don't forget the repopulation of the map

if you don't specify the capacity on the new map you will get quite a bit of overhead on the newly created map because of rehashes (which each are O(n) (at the time) and happen O(log(n)) times while this might amortize to O(n) total but if they don't happen in the first place you will still be better of)

this won't happen with the cleared map because the capacity doesn't change

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
2

I think calling new HashMap() is a better idea since it will not have to do as much processing as clearing the hashmap. Also, by creating a new hashmap you are removing the chance that the hashmap may still be binded to the control that uses the data, which would cause problems when the hashmap is to be cleared.

A. Abiri
  • 10,750
  • 4
  • 30
  • 31
1

The map.clear() that will remove all data. Note that this will only discard all entries, but keep the internal array used to store the entries at the same size (rather than shrinking to an initial capacity). If you also need to eliminate that, the easiest way would be to discard the whole HashMap and replace it with a new instance. That of course only works if you control who has a pointer to the map.

As for reclaiming the memory, you will have to let the garbage collector do its work.

Are your values also Long? In this case, you may want to look at a more (memory-) efficient implementation than the generic HashMap, such as the TLongLongHashMap found in the GNU Trove library. That should save a lot of memory.

Pratik
  • 30,639
  • 18
  • 84
  • 159