While writing an application that must allocate many objects, I received an exception java.lang.OutOfMemoryError: Java heap space
. On reading How to deal with “java.lang.OutOfMemoryError: Java heap space” error (64MB heap size) and java.lang.OutOfMemoryError: Java heap space I tried to run java -jar myJar.jar -Xms1024m -Xmx4096m
command, but the application crashes regardless once it allocates about 1.457 GB. This is in 64bit Win XP box. With or w/o -Xmx the moment of crash remains the same in terms of mem usage of java.exe process. Should not a 64 bit application be able to use 4 GB of RAM in a 64 bit OS?
-
You're not supposed to give Java more than half of the available memory on your machine. Have you tried setting the heap space by `-XX:MaxPermSize-300m` instead? That may help more with running out of heap than setting the maximum allotted memory. – Makoto Nov 10 '13 at 23:40
-
1How much memory does the psychical machine have? – Thorbjørn Ravn Andersen Nov 10 '13 at 23:45
-
Are you using a 64bit JVM? This sounds exactly like you're not doing that. – Anya Shenanigans Nov 11 '13 at 00:18
-
The box has 8 GB. JVM is 64 bit as stated. – ajeh Nov 11 '13 at 14:31
2 Answers
This is a very complex topic. There is no simple solution as one or two parameters that can avoid OOM. Nonetheless, there are some very useful concepts and techniques we can apply in order to get the problem solved.
In fact, you can perform an initial analysis using a dump file from an OOM, by using argument like -XX:-HeapDumpOnOutOfMemoryError. Your analysis should focus on which part is being used up. Is it the heap, or perm generation? And how your objects in the heap is distributed, like what is the size of the largest object(s)/class(es) when an OOM happens. Tools like MAT is an excellent tool.
OOM could happen in the heap.
Increase heap size by -Xmx. (It appears this doesn't apply to your case). Yet I would advise you set -Xms to 4G as well so as to see if you do have enough memory and can reserve for your JVM process. If you could still hit OOM then a fragmentation issue could be the reason. This means, after running for a considerable amount of time with memory block allocated and freed, your heap is fragmented and there is no large continuous space for allocation requests for huge objects. For example, if the largest continuous empty space in the heap is 200M - though the total empty space in the heap is 2G - and if your application requests for a large Object, say an array of size 250M, you hit an OOM. Enabling gc logs and employ an GC log analyzer can give you information in this regard. Please also refer to This blog for better understanding and advice on how to avoid fragmentation.
OOM could happen in the perm area.
Increase perm size by -XX:MaxPermSize=384m. Perm implies the area used for class meta data and static variables. If your application (or the libraries your program uses) loads large amount of classes, or dynamically loads many classes, you might need a larger perm size. If increasing the size doesn't work, you might have leakage in class loading. MAT or memory leak detector should be utilized for investigation then.
Finally, different JVM brands and versions vary in terms of memory structure and parameters. For example, "In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application." So, be sure to check documentation of the version of JDK you are using.

- 1
- 1

- 1,758
- 15
- 16
-
Let's try to limit the discussion to a Oracle's JRE 8ea. I don't use any different brands. – ajeh Nov 13 '13 at 18:46
-
You can allocate 64 GB heaps on 64-bit windows with a 64-bit JVM. (Or much larger but I haven't tried)
If you are getting an OutOfMemoryError it means you could not allocate more objects either because
- you are using more than you think or
- your memory is heavily fragmented e.g. CMS doesn't defrag the tenured space.
E.g. say you gave no more than 4 KB of continuous memory, and you are using CMS which doesn't defragment the memory and you grow a collection like ArrayList or StringBuidler or HashMap, it cannot allocate the object and thus throws an OutOfMemoryError.

- 525,659
- 79
- 751
- 1,130
-
Neither using more memory than Windows task manager thinks (making a point that it is not me who 'thinks' how much memory is used) nor memory is heavily fragmented. Crash can be avoided if I purposely slow down allocation, for example by introducing heavy disk activity by another process and my Java app has to wait for IO to get object resources. Then memory count goes up further than 1.457 MB and reaches over 2 GB at which point initialization is complete and the app works. To me it sounds like garbage collector not catching up and some JVM bug causing a crash. – ajeh Nov 13 '13 at 18:44