5

我们正在监控 jvm 指标,如堆、元空间、线程和 gc 计数,我们能够将这些指标推送到监控服务器,如 prometheus。同样,我们想跟踪 Java 本机内存指标(jcmd VM.sumary 的输出)。我的问题是,是否可以通过调用任何 jvm 运行时类来获取这些指标?

4

4 回答 4

8

是的,可以直接从 Java 应用程序获取 NativeMemoryTracking 总结:

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);
    }
}

不过,您必须解析文本输出。

请注意,可以使用指定的 MBean 单独跟踪 NMT 报告中最重要的部分,包括

  • Java 堆
  • 代码缓存
  • 元空间
  • 压缩类空间
  • 直接字节缓冲区和映射字节缓冲区

请参阅MemoryPoolMXBeanBufferPoolMXBean

正如我在评论中所说,监控 NMT 输出在实践中并不总是有帮助,因为它不能直接反映进程使用的实际物理内存。NMT 可以报告比实际使用量少得多的内存,或者它也可以从操作系统的角度报告比进程消耗更多的内存。

由于 NMT 可能会错过 Java 进程消耗的大量操作系统内存,因此监视进程的驻留集大小 (RSS) 也很有用。在 Linux 上,这可以通过解析/proc/[pid]/stat/proc/[pid]/status.

于 2019-08-13T22:01:38.183 回答
1

你可以在JMX中找到很多你想要的东西。问题“为什么使用 JMX 技术?”的答案之一 是“监视和管理 Java VM”。在Oracle 文档中:

Java 虚拟机 (Java VM) 使用 JMX 技术进行了高度检测。您可以启动 JMX 代理来访问内置的 Java VM 工具,从而远程监控和管理Java VM。

//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();
于 2019-08-12T09:32:55.627 回答
1

我认为没有Java API。您最好的选择可能是调用该jcmd <PID> VM.native_memory命令并解析其输出。当然,您需要首先为您的进程启用本机内存跟踪。

于 2019-08-12T04:27:52.553 回答
0

尽管您没有提及Micrometer,但我想指出我编写的一个小支持库,用于获取诸如 Resident Set Size (RSS) 之类的 procfs 信息。也许您可以从中提取一些有用的代码。实际上,procfs 代码与 Micrometer 无关(尽管不被视为公共 API)。这是:https ://github.com/mweirauch/micrometer-jvm-extras

于 2019-08-12T18:13:20.917 回答