7

I want to process some new data in a HashSet, without any old data needed or the old HashSet object. The old HashSet object isn't referred to elsewhere.

Is it better to simply do hashset = new HashSet<String>() and let JVM to free the memory of the old HashSet object or should I call hashSet.clear() and reuse the same HashSet?

According to openJDK, hashSet.clear() is:

public void clear() {
    map.clear();
}

and map.clear() :

public void clear() {
     modCount++;
     Entry[] tab = table;
     for (int i = 0; i < tab.length; i++)
         tab[i] = null;
     size = 0;
 }

Since map.clear() iterates all the entries, will it be time consuming when the hashSet is large? Which one is recommended in this case, the constructor method or the clear() method?

wings
  • 791
  • 6
  • 21
  • 4
    How about just **hashSet = null;**? – Aniket Thakur Aug 29 '13 at 11:41
  • @AniketThakur Well, in fact, I need a new hashSet. Is it also necessary to assign the hashSet to null if I'm going to new a hashSet afterwards? – wings Aug 29 '13 at 12:15
  • @wings No. Don't set it to null. If you need a new HashSet, make one. Or, possibly better would be to use a different variable, since the new HashSet is probably going to be used for something else. – Eric Stein Aug 29 '13 at 13:00

7 Answers7

6

Simple don't reference your HashSet anymore and let the garbage collector do the work.

Clearing the HashSet before dereferencing it does not free the memory any faster.

Uwe Plonus
  • 9,803
  • 4
  • 41
  • 48
4

Clearing the HashSet is unnecessary - just remove all references to the HashSet (which happens if you write hashset = new HashSet<>();, assuming the old HashSet is not referenced anywhere else) and the garbage collector will do the rest.

Also note that, assuming you need a new HashSet of the same size, calling hashset.clear() takes more time than simply creating a new one with the appropriate capacity

Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
  • 2
    So your solution for freeing up memory is to allocate more memory? That doesn't make any sense. The object will clear when it's out of scope. You're just replacing one map with another. – Eric Stein Aug 29 '13 at 11:33
  • @EricStein I assumed that the OP needs a new HashSet - otherwise it makes no sense indeed. I have clarified that. – assylias Aug 29 '13 at 11:34
  • @assylias Thank you, it's really helpful. Can you also tell me, do I need to assign the old hashSet to null? Does it help "notify" the GC to free the memory? And if it is no use assigning every entry in the hashSet to null, why should jdk itself provid a clear() function like that instead of simply new a hashSet? Is it for memory capacity reasons? – wings Aug 29 '13 at 12:04
  • 2
    @wings The memory will not be release fastre if you assign `null` to any variable. The garbage collector frees up memory if it is full. – Uwe Plonus Aug 29 '13 at 12:24
  • 1
    @wings you cannot replace an object in itself. Therefore collections only have the possibility to set all references to `null`. From outside you can simply create a new object. – Uwe Plonus Aug 29 '13 at 12:36
3

I think there is a misconception here. You don't free memory in java manually. Even if you call System.gc(); that does not guarantee that the GC will be run at that moment.

As for your question: I think that you should use your references in the smallest possible scope and when the code leaves the scope of your Set the reference to it simply gets dropped and the GC will collect it.

clear(); I think is recommended to use if you have some further work with the Set: for example if you processed the data in it and you are preparing to put some other data in it.

In practice I almost never see explicit mySet = null; (this is what you should use if you want explicit dereferencing because mySet = new HashSet<>() does not make any sense) statements because it is much easier and less cumbersome to just use the appropriate scope.

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
2

It is not possible to free memory in java. All you can do is let the VM know it's okay to free it if and when it wants to. That will happen normally when things go out of scope. In general, it's okay to not worry about it. If you've profiled your app and you see a memory leak, then you can try to find it.

Definitely don't make a new HashSet. clear() will remove all the items from the HashSet, but it still won't be collected until it's out of scope.

Eric Stein
  • 13,209
  • 3
  • 37
  • 52
  • Thank you. But I don't quite understand you with "Definitely don't make a new HashSet". Could you explain it further more? – wings Aug 29 '13 at 12:07
  • @wings if you need a new object, make a new object. Don't just create one to remove the reference to the old one. – Eric Stein Aug 29 '13 at 13:05
0

If you don't have any references to your objects garbage collector removes them automatically. You do not need to do it manually.

Ean V
  • 5,091
  • 5
  • 31
  • 39
0

It depends, if you have very small sized maps then in that case clearing would be better than spawning Objects.

And if you have lots of items in your maps then it is not even worth clearing it. As if you see the clear() method's implementation it iterates over all the elements. In that case creating new object would be a bit cheaper.

But generally it is a good idea to let the Garbage collector take care of clearing up things and you go on creating new objects while the left over reference will be cleared by Garbage collector.

But as a rule of thumb one should try and limit the number of objects being created. As I said it depends.

Amar
  • 11,930
  • 5
  • 50
  • 73
0

The memory management is done by JVM itself. So even if you make the memory free manually or not that will be garbage collected automatically anyway.

The garbage collector reduces the coding effort regarding memory management.