Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JVM sending back memory to OS [duplicate]

I have a question regarding the JVM memory management (at least for the SUN's one).

I would like to know how to control the fact that the JVM send the unused memory back to the OS (windows in my case).

I wrote a simple java program to illustrate what I expect. Run it with -Dcom.sun.management.jmxremote option so that you can also monitor the heap with jconsole for example.

With the following program:

package fr.brouillard.jvm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

public class MemoryFree {
    private BufferedReader reader = new BufferedReader(new
        InputStreamReader(System.in));
    private List<byte[]> usedMemory = new LinkedList<byte[]>();
    private int totalMB = 0;
    private int gcTimes = 0;

    public void allocate(int howManyMB) {
        usedMemory.add(new byte[howManyMB * 1024 * 1024]);
        totalMB += howManyMB;
        System.out.println(howManyMB + "MB allocated, total allocated: " +
                totalMB + "MB");
    }

    public void free() {
        usedMemory.clear();
    }

    public void gc() {
        System.gc();
        System.out.println("GC " + (++gcTimes) + " times" );
    }

    public void waitAnswer(String msg) {
        System.out.println("Press [enter]" + ((msg==null)?"":msg));
        try {
            reader.readLine();
        } catch (IOException e) {
        }
    }

    public static void main(String[] args) {
        MemoryFree mf = new MemoryFree();
        mf.waitAnswer(" to allocate memory");
        mf.allocate(20);
        mf.allocate(10);
        mf.allocate(15);
        mf.waitAnswer(" to free memory");
        mf.free();
        mf.waitAnswer(" to GC");
        mf.gc();
        mf.waitAnswer(" to GC");
        mf.gc();
        mf.waitAnswer(" to GC");
        mf.gc();
        mf.waitAnswer(" to GC");
        mf.gc();
        mf.waitAnswer(" to exit the program");

        try {
            mf.reader.close();
        } catch (IOException e) {}
    }
}

The internal heap is free once the first GC is done (what is expected) but the memory is only sent back to the OS starting from the third GC. After the fourth, the full allocated memory is sent back to the OS.

How to setup the JVM to control this behaviour? In fact my problem is that I need to run several CITRIX clients sessions on a server, but I would like the running JVMs on the server to free the memory as soon as possible (I have only few high consuming memory functions in my application).

If this behaviour cannot be controlled, can I let it like this and increase instead the OS virtual memory and let the OS using it as it wants without big performance issues. For example, would there be issues to have 10 java process of 1GB memory (with only 100MB real allocated objects in the heap) on a 4GB server with enough virtual memory of course.

I guess that other people already faced such questions/problems.

Thanks for your help.

like image 706
Matthieu BROUILLARD Avatar asked Mar 23 '09 23:03

Matthieu BROUILLARD


People also ask

Does JVM return memory to OS?

The HotSpot JVM does release memory back to the OS, but does so reluctantly since resizing the heap is expensive and it is assumed that if you needed that heap once you'll need it again.

What is JVM memory usage?

An interesting area when sizing the JVM is the JIT's code cache. By default, the HotSpot JVM will use up to 240MB. If the code cache is too small the JIT will run out of space to store its output and performance will suffer as a result. If the cache is too large, memory may be wasted.

How much memory does a Java thread consume?

Be mindful of thread use and stack size. The default option -Xss512k means that each thread will use 512kb of memory. The JVM default without this option is 1MB.

What is MinHeapFreeRatio?

-XX:MinHeapFreeRatio: sets the minimum percentage of heap free after GC to avoid expansion; to monitor the heap usage you can use VisualVM shipped with JDK.

Does JVM release memory back to the operating system?

Mostly Java It does largely depend on the JVM implementation. In general, a JVM can/will release memory back to the operating system, but it tends to do so reluctantly because allocating memory from the OS is much more expensive that allocating memory from within the JVM’s own heap.

Can JVM memory usage be more than-XMX value under peak business load?

Therefore, JVM memory usage can be more than the -Xmx value under peak business load. Metaspace: Stores information about the classes and methods used in the application. This storage area was called Permanent Generation or perm in the HotSpot JVM prior to JDK 8, and the area was contiguous with the Java heap.

What is the use of heap in JVM?

Permanent Generation (the name prior to JDK 8) or Metaspace (the name from JDK 8 onward), the CodeCache, the native C++ heap used by other JVM internals, space for the thread stacks, direct byte buffers, garbage collection overhead, and other things are counted as part of the JVM's memory consumption.

What does the-XMX parameter of the JVM mean?

The value of the -Xmx parameter specifies the maximum size of the Java heap, but that is not the only memory consumed by the JVM.


1 Answers

To control return of heap to the OS, from Java 5 onward, use the -XX:MaxHeapFreeRatio option, as described in the tuning guide.

If you feel your question is meaningfully different from this one, please point out how.

like image 56
erickson Avatar answered Oct 15 '22 06:10

erickson