Re: How to get the current allocated total size of an ArrayList?
On 02/23/2011 10:50 AM, markspace wrote:
On 2/23/2011 7:43 AM, Robin Wenger wrote:
Assume I setup an ArrayList like:
ArrayList<String> mylines = new ArrayList<String>();
and add lots of lines/strings to it:
while(...)
mylines.add(...);
How can I find out the total size (in Bytes) which is currently allocated by
the ArrayList?
Occasionally I get an OutOfMemory exception [sic]. Can I prevent this by
preallocating everything in one step
in advance instead of doing this little by little with every add()?
No.
This post has followups set to cljp, btw, for those reading cljh.
How annoying.
The amount of memory involved is hard to estimate without more details.
Strings don't always live on the heap.
If you're getting OutOfMemoryError (OOME) [1] it's not necessarily (or even
likely) the strings that are causing it. If they are, then you should
consider external storage for the data.
More likely, and your question implies that this is relevant, you are failing
to let the garbage collector (GC) do its job. [2] [3] [4]
While Java cannot have memory leaks in the classic sense, it can have
so-called "memory leaks", more nearly characterized as memory packratting,
where your program keeps a reference alive after it's finished with it. This
is the usual cause of OOME.
While usually you would avoid the practice of explicit nulling ('foo = null;')
to release memory, there are a few times when you need it. [2] These include
spurious references held by collections, which might apply to you.
If you don't let references die, the sooner the better, the GC cannot do its
job. Objects that live too long move to the geriatric heap ("tenured
generation") and are tougher to kill. You want to slay them young - create
instances to the most local appropriate scope and avoid long-lived references
to them in collections and elsewhere.
Strings are a bit of a special case. If your strings are constants, i.e.,
declared using quoted literals ( "some content" ), they are stored in the
'String' intern pool and that's that. Strings declared via 'new String()',
either implicitly or explicitly, usually live on the heap. So your memory
allocation for that 'List' depends in part on where the strings come from.
The optimizer can mess with your calculations, too. But most likely figuring
the size of your 'List' is not going to help. If it's really that big,
consider buying a cartload of RAM and running 64-bit, or moving to external
resources for the strings. (DBMS or doc-management system, anyone?)
Profilers and similar tools, including those inbuilt to Java, help you
determine if you have a packratting problem, which if I were to wish to make
money I'd bet you do. Except no one would take the bet.
Since you haven't shared your code with us, all we can do is speculate. [5]
[1]
<http://download.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html>
[2]
<http://www.ibm.com/developerworks/java/library/j-jtp01274.html>
See also:
[3]
<http://www.ibm.com/developerworks/java/library/j-jtp03216.html>
[4]
<http://www.ibm.com/developerworks/java/library/j-jtp09275.html>
[5]
http://sscce.org/
--
Lew
Honi soit qui mal y pense.