Monitoring java native memory

2020-07-18 09:27发布

We are monitoring jvm metrics like heap, metaspace, threads and gc count and we are able to push these metrics to monitorng server like prometheus. Similarly we wanted to track Java native memory metrics(output of jcmd VM.sumary). My question is, is it possible to get these metrics by calling any jvm runtime classes?

4条回答
Melony?
2楼-- · 2020-07-18 10:15

Yes, it is possible to get NativeMemoryTracking summary directly from a Java application:

import javax.management.JMException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;

public class DiagnosticCommand {

    public static String execute(String command, String... args) throws JMException {
        return (String) ManagementFactory.getPlatformMBeanServer().invoke(
                new ObjectName("com.sun.management:type=DiagnosticCommand"),
                command,
                new Object[]{args},
                new String[]{"[Ljava.lang.String;"});
    }

    public static void main(String[] args) throws Exception {
        String summary = DiagnosticCommand.execute("vmNativeMemory", "summary");
        System.out.println(summary);
    }
}

You'll have to parse the text output though.

Note that the most important parts of the NMT report can be tracked separately with the designated MBeans, including

  • Java Heap
  • Code Cache
  • Metaspace
  • Compressed Class Space
  • Direct Byte Buffers and Mapped Byte Buffers

See MemoryPoolMXBean and BufferPoolMXBean.

As I told in the comments, monitoring NMT output is not always helpful in practice, since it does not directly reflect the actual physical memory used by the process. NMT can report much less memory than the actual usage, or it can also report more memory than the process consumes from the OS perspective.

Since NMT can miss the large amount of OS memory consumed by a Java process, it's also useful to monitor the process' resident set size (RSS). On Linux this can be done by parsing /proc/[pid]/stat or /proc/[pid]/status.

查看更多
女痞
3楼-- · 2020-07-18 10:16

I don't think there's a Java API for that. Your best bet might be to invoke the jcmd <PID> VM.native_memory command and parse its output. Of course, you need to enable native memory tracking for your process first.

查看更多
来,给爷笑一个
4楼-- · 2020-07-18 10:22

You can find many things you want in JMX. One of the answers to question "Why Use JMX Technology?" is "Monitor and manage the Java VM". In Oracle doc:

The Java Virtual Machine (Java VM) is highly instrumented using the JMX technology. You can start a JMX agent to access the built-in Java VM instrumentation, and thereby monitor and manage a Java VM remotely.

//Metaspace
for (MemoryPoolMXBean memoryMXBean : ManagementFactory.getMemoryPoolMXBeans()) {
    if ("Metaspace".equals(memoryMXBean.getName())) {
            System.out.println(memoryMXBean.getUsage().getUsed());
            System.out.println(memoryMXBean.getUsage().getCommitted());
            System.out.println(memoryMXBean.getUsage().getMax());
            System.out.println(memoryMXBean.getUsage().getInit());
    }
}

//current number of live threads including both daemon and non-daemon threads
int threadCount = ManagementFactory.getThreadMXBean().getThreadCount();

//Returns the current memory usage of the heap and non-heap
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapMemory = memoryMXBean.getHeapMemoryUsage();
MemoryUsage nonHeapMemory = memoryMXBean.getNonHeapMemoryUsage();

//GarbageCollector total number of collections
List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
long totalCollectionCount = garbageCollectorMXBeans.stream().mapToLong(x -> x.getCollectionCount()).sum();
查看更多
够拽才男人
5楼-- · 2020-07-18 10:25

Allthough you don't mention Micrometer, I'd like to point out a little support library I have written for getting ahold of the procfs information like Resident Set Size (RSS). Perhaps you can extract some useful code out of it. Actually the procfs-code is not Micrometer-related (allthough not considered public API). Here it is: https://github.com/mweirauch/micrometer-jvm-extras

查看更多
登录 后发表回答