Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to measure direct memory usage in Java?

Tags:

java

memory

nio

If I create a buffer via ByteBuffer.allocateDirect(), the memory exists outside of the Java heap. Is there a way to measure this kind of memory usage from my application in a cross-platform way similar to how I can measure Java heap usage with Runtime.totalMemory() and Runtime.freeMemory()?

like image 604
martinez314 Avatar asked Nov 18 '13 21:11

martinez314


People also ask

How do I check Java memory usage?

Using VisualVM (jvisualvm) jvisualvm is a tool to analyse the runtime behavior of your Java application. It allows you to trace a running Java program and see its the memory and CPU consumption. You can also use it to create a memory heap dump to analyze the objects in the heap.

What is direct memory Java?

The direct buffer memory is the OS' native memory, which is used by the JVM process, not in the JVM heap. It is used by Java NIO to quickly write data to network or disk; no need to copy between JVM heap and native memory.

How do I get track of internal memory of a JVM?

Get summary data: To get a summary view of native memory usage, start the JVM with command line option: -XX:NativeMemoryTracking=summary . Example 2-2 is a sample output that describes NMT for track level set to summary. One way to get this sample output is to run: jcmd <pid> VM. native_memory summary .


2 Answers

You can use reflections to get Bits.reservedMemory on OpenJDK/HotSpot Java 7. There is no platform independent way and this only shows you the usage via ByteBuffer.allocateDirect() not any other way of allocating native memory.

An alternative is to parse /proc/{pid}/maps and exclude file mappings. This is an approximation of the virtual memory your process is using.

like image 171
Peter Lawrey Avatar answered Sep 28 '22 08:09

Peter Lawrey


You can use MXBeans to get the memory used by the direct byte buffers and mapped byte buffers:

List<BufferPoolMXBean> pools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
for (BufferPoolMXBean pool : pools) {
    System.out.println(pool.getName());
    System.out.println(pool.getCount());
    System.out.println("memory used " + toMB(pool.getMemoryUsed()));
    System.out.println("total capacity" + toMB(pool.getTotalCapacity()));
    System.out.println();
}

prints something like:

direct
122
memory used 456.1562509536743 MB
total capacity456.15625 MB

mapped
0
memory used 0.0 MB
total capacity0.0 MB

where toMB function is this:

private static String toMB(long init) {
    return (Long.valueOf(init).doubleValue() / (1024 * 1024)) + " MB";
}

However, I am not 100% sure if direct byte buffers are the only things that can live in the direct memory. Perhaps there are other things...

like image 35
Ali Ok Avatar answered Sep 28 '22 07:09

Ali Ok