views:

71

answers:

2

I have a system which cannot provide more than 1.5 Gb for Java process. Thus i need an exact way to specify java process settings, including all memory kinds inside java and possible fork.

One specific java process and system to illustrate my problem:

My current environment is java 1.6.0_18 under Ubuntu Linux 9.10.

I start large java server process with following JVM Options: "-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m"

Now, "top" command reports that the process uses 1.6gb memory...

Questions:

1 - how the maximal space used by java process is calculated? Please provide exact formula if possible. ( Smth. Like: max.heap + max.perm + stack + jvm space = maximal space )

2 - what is the infamous fork behavior under linux in my case? Will the forked JVM occupy extra 1.6 gb (resulting in total 3.2 Gb of used memory)?

3 - Which options must be used to absolutely ensure that no more than 1.5gb is used at any time?

thank you

@rancidfishbreath: "ulimit" will ensure that java cannot take more than specified amount of memory. My purpose is to ensure that java doesn't ever try to do that.

+1  A: 

top reports 1.6GB because PermSize is ON TOP of the heap-size maximum heap size. In your case you set MaxPermSize to 512m and Xmx to 1024m. This amounts to 1536m. Just like in other languages, an absolutely precise number can not be calculated unless you know precisely how many threads are started, how many file handles are used, etc. The stack size per thread depends on the OS and JDK version, in your case its 1024k (if it is a 64bit machine). So if you have 10 threads you use 10240k extra as the stack is not allocated from the heap (Xmx). Most applications that behave nicely work perfectly when setting a lower stack and MaxPermSize. Try to set the ThreadStackSize to 128k and if you get a StackOverflowError (i.e. if you do lots of deep recursions) you can increase it in small steps until the problem disappears.

So my answer is essentially that you can not control it down to the MB how much the Java process will use, but you come fairly close by setting i.e. -Xmx1024m -XX:MaxPermSize=384m and -XX:ThreadStackSize=128k -XX:+UseCompressedOops. Even if you have lots of threads you will still have plenty of headroom until you reach 1.5GB. The UseCompressedOops tells the VM to use narrow pointers even when running on a 64bit JVM, thus saving some memory.

sicn
that helps me further. Thank you sicn
Dimitri Uwarov
A: 

At high level JVM address space is divided in three main parts 1. kernel space( ~1gig,also depends on platform,windows its more then 1 gig) 2. Java Heap (Java heap specified by user using the -Xmx,-XX:MaxPermSize etc. 3. Rest virtual address space goes to native usage of JVM,to accomodate the malloc/calloc did by JVM,native threads stack(thread respective the java threads and addition JVM native threads for GC etc).

So you have (4 gig - kernel space 1gig to 1.25 gig) ~2.75 gig to play with,so you can set your java/native heap accordingly. But generally we should keep atleast 500mb for JVM native heap else there is a chances that you get native oom.So we need to do a trade off here based on your application's java heap utilization.

Anil Vishnoi