How to calculate (and specify) the total memory space allowed for java process?

14,731

Solution 1

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.

Solution 2

At high level JVM address space is divided in three main parts:

  1. kernel space: ~1GB, also depends on platform, windows its more than 1GB
  2. Java Heap: Java heap specified by user using the -Xmx, -XX:MaxPermSize, etc...
  3. Rest of virtual address space goes to native usage of JVM, to accomodate the malloc/calloc done by JVM, native threads stack: thread respective the java threads and addition JVM native threads for GC, etc...

So you have (4GB - kernel space 1-1.25GB) ~2.75GB 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.

Share:
14,731
Dimitri Uwarov
Author by

Dimitri Uwarov

Updated on June 29, 2022

Comments

  • Dimitri Uwarov
    Dimitri Uwarov almost 2 years

    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.