Thursday, June 28, 2007

java outofmemory in linux

Debian is a stable easy to maintain platform for Java Web Applications. However if you start using some caching frameworks, you may need to do some JVM tuning and here's the information you need to know.

Read this and to the point where you understand that a 32-process on Linux only has 2GB of addressible space. In fact, back in 1999, Linus decreed that 32-bit Linux would never, ever support more than 2GB of memory. "This is not negotiable."

Stacks are memory chunks used for saving variables and passing parameters when calling functions. It's a low level implementation detail, but the important thing to know is that each thread in each process must have it's own stack. Big stacks add up quickly as in the case of tomcat and most web servers where many threads are used to serve requests. Stacks for threads all come out of the same address space, so if you only used memory for stacks of threads you could have 1024 threads with 2MB stacks. In fact in Debian Sarge, there is no way to reduce the amount of memory allocated for the stack of a thread. [1] [2] [3]. Understand that this is not java specific, the same limitation applies to c programs.

Now that we have some fundamental stuff down, it's easy from here. Say you have 2G of Memory and want to use as much memory as possible for your cash for performance considerations. The objects in the cash will be stored in the heap memory. I think you should calculate how much memory you should use with the following formula.

HeapMemory = ProcessAdressSpace - ThreadMemory - PermGen - JVM

If you're running 32-bit, you can only see 2G max.

ProcessAdressSpace = 2G

If you web app is like mine, you'll need 100 threads. Have some librarys that may create threads, tack on another 100 to be safe. 200 threads X 2Mb/Thread = 400M

ThreadMemory = 400M

PermGen is where your defined classes go. Since you use alot of frameworks and have lots of classes, you should set this to 128M

PermGen = 128M

JVM is relatively small, but you need to give it room so that it can work quickly.

JVM = 256M

With those parameters, HeapMemory should not exceed 1264M! Anything more and you're going to slow down your application more than the cache is speeding it up, or you'll introduce nasty a OutOfMemoryException that will drive you crazy. Here's the parameters you want to use.

java -Xmx1264M -XX:MaxPermSize=128m ...

If you upgrade to etch, and set the stack size to 1MB (not recommending without extensive testing), then you can reclaim another 200MB for the heap.

No comments:

Post a Comment