【问题标题】:Is there a way to measure direct memory usage in Java?有没有办法测量 Java 中的直接内存使用情况?
【发布时间】:2013-11-18 21:39:14
【问题描述】:

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

【问题讨论】:

    标签: java memory nio


    【解决方案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 上使用反射来获取 Bits.reservedMemory。没有独立于平台的方式,这仅向您显示通过 ByteBuffer.allocateDirect() 的使用情况,而不是任何其他分配本机内存的方式。

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

      【讨论】:

      • 我能够通过sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getMemoryUsed()sun.misc.VM.maxDirectMemory() 获得价值。比反射好还是坏?
      • @whiskeyspider 比使用反射更简单。
      • 附带说明,如果SharedSecrets 是通过低级Unsafe.allocateMemory() 分配的,则不会显示已用内存,在这种情况下,您应该自己跟踪/计算分配的内存或解析@ 987654327@ 如答案。
      • @ZaurGuliyev 了解更多详情 /proc/self/smaps,其中甚至包括多少内存是私有的以及内存中与磁盘上的内存。
      猜你喜欢
      • 2018-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 2016-01-10
      相关资源
      最近更新 更多