有没有办法在Java中测量直接内存使用情况?

2022-09-03 07:07:43

如果我通过 创建缓冲区,则内存存在于 Java 堆之外。有没有办法以跨平台的方式从我的应用程序中测量这种内存使用情况,类似于我如何使用 和 来测量 Java 堆使用情况?ByteBuffer.allocateDirect()Runtime.totalMemory()Runtime.freeMemory()


答案 1

您可以使用 MXBeans 获取直接字节缓冲区和映射字节缓冲区使用的内存:

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

打印如下内容:

direct
122
memory used 456.1562509536743 MB
total capacity456.15625 MB

mapped
0
memory used 0.0 MB
total capacity0.0 MB

其中 toMB 函数是这样的:

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

但是,我不能100%确定直接字节缓冲区是否是唯一可以存在于直接内存中的东西。也许还有其他事情...


答案 2

你可以使用反射来访问 OpenJDK/HotSpot Java 7。没有独立于平台的方式,这只显示了通过ByteBuffer.allocateDirect()的使用情况,而不是任何其他分配本机内存的方式。Bits.reservedMemory

另一种方法是解析和排除文件映射。这是进程正在使用的虚拟内存的近似值。/proc/{pid}/maps