• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

arrayList.clear() VERSUS arrayList = new ArrayList()

 
Ranch Hand
Posts: 224
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm wondering if ArrayList clear() method will release memory allocated for the ArrayList back into the Operating System.

Consider two examples below. In option (1.), after I call arrayList.clear(), I know the API says that "The list will be empty after this call returns." But what happen if I have a huge ArrayList then I do "clear()". The list will be empty but how about memory allocated to the ArrayList. Will it be allocated back to the O.S. like option (2.) does?

 
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ArrayList.clear() will just cause the memory allocated to the objects in the ArrayList to become eligible for garbage collection (assuming there are no other references to these objects). The memory allocated to the ArrayList object itself will not be eligible for garbage collection because it still has a reference to it.
 
Susan Smith
Ranch Hand
Posts: 224
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I see. So it seems that arrayList.clear() is prone to memory leak.
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Susan Smith:
I see. So it seems that arrayList.clear() is prone to memory leak.



No. All the objects that were in the list have become aligible for garbage collection. The list itself is not eligible for garbage collection because you still have a reference to it. If that reference were to go out of scope then the list could also be garbage collected.
It's only as prone to memory leakage as any other object that you keep a reference to.
 
Susan Smith
Ranch Hand
Posts: 224
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But isn't this what happen:

1.) I create a new list with 100 items. The list now has 100 object pointers. Each pointer in the list reference to an object somewhere in memory.

2.) Then I call clear(); Now all the objects referenced by the pointer in the list have become eligible for garbage collection. But the list itself still uses memory to keep 100 object pointers.

3.) Then if I fill in the list with 5 more items. Then I have a list with 5 items but the memory size used by the list is stil for 100 object pointers.

Is this correct?
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Susan - that's correct. At least for the current implementation of ArrayList, and I think it's always been true. You can use the trimToSize() method to fix this if you like. It's not exactly a memory leak in the traditional sense - it doesn't keep growing. But whatever was the maximum size ever used by the ArrayList (for valid non-memory-leak reasons), that maximum size will be retained even when it's no longer necessary.
 
Ranch Hand
Posts: 457
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would generally suggest you don't need to reuse an ArrayList for a different use. If you're done with it, toss it.
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This wasn't mentioned, but should be considered... If the variable reference is referencing an arraylist that is shared by many threads (via different references), calling clear() will clear the one arraylist. Declaring a new arraylist will make the variable reference a different arraylist from the other threads.

Henry
 
Ranch Hand
Posts: 95
Scala Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Bill Shirley:
I would generally suggest you don't need to reuse an ArrayList for a different use. If you're done with it, toss it.



Hi!
You mean this?



Then, that ArrayList is for the GC (a), right?
[ January 26, 2008: Message edited by: Andre Brito ]
 
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Andre Brito:
...Then, that ArrayList is for the GC (a), right?



Yes, that is true. The arraylist object being referenced by the 'a' becomes eligible for GC.

The same holds good for the option (2) suggested by OP. As soon as you assign a new arraylist to the reference variable as an alternative to clear(), the earlier arraylist being referneced by this reference variable becomes eligible for GC until there are no active references to it.
 
Susan Smith
Ranch Hand
Posts: 224
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

Thanks for your reply.


Susan - that's correct. At least for the current implementation of ArrayList, and I think it's always been true. You can use the trimToSize() method to fix this if you like. It's not exactly a memory leak in the traditional sense - it doesn't keep growing. But whatever was the maximum size ever used by the ArrayList (for valid non-memory-leak reasons), that maximum size will be retained even when it's no longer necessary.



Can someone please recommend how do I prove this? I might need to show some proofs to my coworker to ensure them that this is what happen.
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I just looked at the source code for ArrayList, found in src.zip in your JDK installation. The field "elementData" is the one that contains all the entries. Search for all the places that asssign new values to this field. Ignoring those that occur in constructors, deserialization, and cloning, the two places that are relevant here are in ensureCapacity() and trimToSize(). Note that ensureCapacity() is written so that it will never get smaller, only bigger, and this method is called by many others in ArrayList. While trimToSize() is the only method that can make the array smaller, and it's not called automatically by any other methods in this class.

If your co-worker is obstinate or unable/unwilling to follow the code in ArrayList.java, you could write a demo program. Create an ArrayList, and print the value of Runtime.freeMemory(). Then add 100000000 null entries to the list, and print the free memory again. Then call list.clear() and System.gc() - heck, call gc() ten times in a row to give the memory a really good scrubbing - and print the free memory again. You should see that the memory usage has not gone back to normal; it's still taken up by that huge empty ArrayList. Then replace the ArrayList with a new ArrayList(), run gc(), and print the free memory. You should see a big difference.
 
Susan Smith
Ranch Hand
Posts: 224
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Jim,

I wrote some code and it shows that "new ArrayList()" frees up memory a lot. But there is one part that I don't understand from the result. "Free Memory (after adding pointer)" seems to be bigger than the initial "Free Memory (Initial)"



----------------------------
And the result is below:

Free Memory (initial):1198296
Free Memory (after adding pointer):132967888
Free Memory (after clear()):494980672
Free Memory (after new ArrayList()):1016721528
Press any key to continue...
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, using freeMemory() is a bit of an oversimplification here. The problem is that as you run the program, it allocates more memory for the process (based on your -Xms and -Xmx settings). So at the end, more memory is available because the process grew in size as it ran. To look at how much has been used, try something like this:

The last column is the one you care about, but the other columns may help you understand what's going on.
 
Susan Smith
Ranch Hand
Posts: 224
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Now it makes more sense.

Below is the result:
 
Susan Smith
Ranch Hand
Posts: 224
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for the help!
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic