【问题标题】:What is contained in code/internal sections of JCMD?JCMD 的代码/内部部分包含什么?
【发布时间】:2018-04-28 19:44:49
【问题描述】:

为基于 JVM 的服务确定 docker 容器的尺寸是很棘手的(众所周知)。我很确定我们稍微缩小了容器的尺寸,并想澄清一些与我们在监控时看到的特定 jcmd(本机内存跟踪器)输出有关的问题。

问题:

JCMD output 在这里。

Direct Byte Buffers JMX 属性在这里。

一些背景细节:

设置:

  • 基于 Spring Boot 的应用程序
  • JVM 选项:

    -server -Xms1792m -Xmx1792m -XX:MetaspaceSize=128M - XX:MaxMetaspaceSize=192M -XX:+UseG1GC -XX:+UseStringDeduplication - XX:MaxDirectMemorySize=256m -XX:NativeMemoryTracking=detail

  • Docker 容器 2500MiB 在 AWS/EC2 中运行

【问题讨论】:

    标签: java linux memory-management jvm jcmd


    【解决方案1】:

    jcmd 报告的“内部”中是否包含直接字节缓冲区?

    (更新) ByteBuffer.allocateDirect 内部调用 Unsafe.allocateMemory 其中 is counted 由 NMT 在内部部分(由 mtInternal 常量表示)。

    相反,MappedByteBuffers(由FileChannel.map 获得)不会反映在 NMT 报告中,尽管从操作系统的角度来看,它们肯定会影响进程使用的内存量。

    jcmd 报告的“代码”中除了代码缓存之外还有什么?

    用于维护已编译代码和生成的运行时存根的辅助 VM 结构:哈希表、代码字符串、适配器指纹等。与 CodeCache 本身相比,它们都相当小。这些结构构成了报告中的“malloc”部分,而 CodeCache 进入了“mmap”部分。

    有没有一个好的方法来限制 jcmd 报告的“代码”部分。

    关闭分层编译 (-XX:-TieredCompilation) 可能会减少“代码”使用的内存量,只是因为生成的代码会少很多。但请确保您了解什么是分层编译以及它可能对性能产生什么影响。

    【讨论】:

    • 我很确定直接字节缓冲区在“内部”中。我问,因为我没有在任何地方看到正式的记录,并希望有人可以指出我的官方内容。根据我自己的测试,我很确定他们是。这个要点gist.github.com/prasanthj/48e7063cac88eb396bc9961fb3149b58 也表明他们确实在那里。
    • @RonanB 抱歉让您感到困惑 - 我在考虑 MappedByteBuffers。 ByteBuffer.allocateDirect 分配的内存确实进入了 NMT 报告的“内部”部分。我用相关 JVM 源的链接更新了答案。
    猜你喜欢
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多