Sometimes when Java developers code their application, they may face this error message in their log.
To the uninformed, the first remark would be... we don't have enough memory.... but the server has 16GB RAM! WTF?
This particular Java exception error message is a bit misleading. Although it says it is an OOME, the underlying factors are different. In reality, it is an Out of Memory event but this error may occur even when the JVM have plenty of heap to spare.
To explain the reason to this is to understand and go back to basics.
Some of you readers are developers, unlike me. I've retired from programming waaay back in 1993.
If some of you would bother to attend class or at least pay attention to basic concepts of memory usage in computer programs you might recall that in an environment where a program runs there is a memory space.
This space is divided into heap space and stack space. Anyone of you that have taken assembly language programming will understand this better. Look at the memory as a container. The heap space is on top, while the stack space is at the bottom. In the middle space is the free memory as far as the program is concerned.
Logically this heap space builds up as the program executes and grows 'downwards' and the stack space increases upwards as variables and program code are executed. When this two meet, we have an out of memory error.
Back to the main topic of this post. Threads are a resource that is held by the operating system. In those days where applications run on a single thread, this resource is never a problem. Now, in object oriented-based applications, multi-threaded applications are a norm.
As a resource, threads a limited. The limit is determined by several factors which include the Operating System and the CPU bits. Say for an example, in a 32-bit, Red Hat Enterprise Linux v4.x the Operating System thread is defined by a kernel variable named as threads-max . This is the maximum value where the Operating System can allocate to running program threads. Now, within each threads there is a default stack space assigned, which varies from one OS to another. In RHEL 4.x it is about 512K
Threads allocated to a process has a much more lower limit. An example in the same Operating System, a Java 1.5 JVM process can only have a maximum of 1024 threads.
With this basic information we can drill down further on the error.
The above OOME error occurs, when the OS are unable to allocate more memory for the thread stack.
A simple formula can be used to determine (in this case a JVM) total RAM usage size.
(heap size) + (number of threads)x(thread stack size) = (total RAM used by JVM process).
Let's say that:
the heap size assigned (java -Xmx value) for the JVM is 2048MB,
the maximum thread is 1024
the default stack size is 512K
using the formula above, we'll get 2048000 + (1024 x 512) = 2512MB
now, in a 32-bit machine, a maximum memory space that can be allocated for a JVM heap is about 2048MB. This leaves some space (2^32) for other OS needs. This this additional space the stack, PermGen space and others are located. Assuming that we have 256MB allocated for PermGen space this pushes up RAM usage to 2048 + 256 + stack space + OS functions. The total of this value should not exceed 4096MB.
In the example above we have exceeded the space where we can allocate, if the threads usage are pushed to the maximum. 2048 + 256 + (1024 x 512) - 2768MB. This is too high a value for a JVM instance, hence the error.
To compensate, we can adjust any one of the three parameters.
Apart from this, the developer may have to recode and change the way variables are used and how methods are called, avoiding long running calls and recode usage of variables to be of private and released as soon as the situation permits.
Another way is change to a 64-bit environment and understand that as developers you do not just code.
.rr
In the example above we have exceeded the space where we can allocate, if the threads usage are pushed to the maximum. 2048 + 256 + (1024 x 512) - 2768MB. This is too high a value for a JVM instance, hence the error.
To compensate, we can adjust any one of the three parameters.
- Heap Size. If we really need 2048MB then we can only 'play' with the other two parameters.
- Number of Threads. Typically if we change this this to a insufficient value, we will be hit with Thread Exhaustion error if the processes outgrow the thread limits within the JVM.
- Stack Size. Setting this to too low a value will result in Stack overflow error.
Apart from this, the developer may have to recode and change the way variables are used and how methods are called, avoiding long running calls and recode usage of variables to be of private and released as soon as the situation permits.
Another way is change to a 64-bit environment and understand that as developers you do not just code.
.rr
No comments:
Post a Comment