是的,可以直接从 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);
}
}
不过,您必须解析文本输出。
请注意,NMT 报告中最重要的部分可以使用指定的 MBean 单独跟踪,包括
- Java堆
- 代码缓存
- 元空间
- 压缩类空间
- 直接字节缓冲区和映射字节缓冲区
See 内存池MXBean https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html and 缓冲池MXBean https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html.
正如我在评论中所说,监视 NMT 输出在实践中并不总是有帮助,因为它并不直接反映进程使用的实际物理内存。 NMT可以报告少得多 https://stackoverflow.com/questions/44734359/jvm-is-using-more-memory-than-native-memory-tracking-says-how-do-i-locate-where内存比实际使用情况,或者它也可以报告more https://stackoverflow.com/questions/31173374/why-does-a-jvm-report-more-committed-memory-than-the-linux-process-resident-set从操作系统的角度来看,内存比进程消耗的内存要多。
由于 NMT 可能会错过 Java 进程消耗的大量操作系统内存,因此监视进程的驻留集大小 (RSS) 也很有用。在 Linux 上,这可以通过解析来完成/proc/[pid]/stat http://man7.org/linux/man-pages/man5/proc.5.html or /proc/[pid]/status http://man7.org/linux/man-pages/man5/proc.5.html.