8

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

问题:

JCMD 输出在这里。

直接字节缓冲区JMX 属性在这里。

一些背景细节:

设置:

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

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

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

1 回答 1

5

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

(更新) ByteBuffer.allocateDirect内部调用Unsafe.allocateMemory,由 NMT 在内部部分计数(由mtInternal常量表示)。

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

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

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

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

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

于 2017-11-15T18:03:16.237 回答