为基于JVM的服务确定docker容器的尺寸非常困难(众所周知)。我很确定我们的容器尺寸略有不足,并且想清除一些与我在监视时看到的特定jcmd(本机内存跟踪器)输出有关的问题。
问题:
JCMD输出在这里。
直接字节缓冲区 JMX属性在这里。
一些背景细节:
设置:
JVM选项:
-服务器-Xms1792m -Xmx1792m -XX:MetaspaceSize = 128M-XX:MaxMetaspaceSize = 192M -XX:+ UseG1GC -XX:+ UseStringDeduplication-XX:MaxDirectMemorySize = 256m -XX:NativeMemoryTracking = detail
我正在尝试使用以下 2 个命令进行堆转储
jcmd 产生 ~300M 的文件大小,jmap 产生 ~1.4G 的文件大小。为什么这些是不同的大小,我们在 jmap 中有任何其他信息吗?我在 jcmd 中遗漏了一些参数吗?
JDK 是 1.8.0_162
Xms 和 Xmx 是 4G
我试图尝试使用jcmd VM.set_flag选项.但遇到一个错误,"只能设置'可写"标志".什么是可写标志?
得到我的pid:
XXX@XXX-Air:~/javacode$ jcmd -l
6294 Test
6295 jdk.jcmd/sun.tools.jcmd.JCmd -l
Run Code Online (Sandbox Code Playgroud)
试图更改vm标志:
XXX@XXX-Air:~/javacode$ jcmd 6294 VM.set_flag ConcGCThreads 4
6294:
only 'writeable' flags can be set
XXX@XXX-Air:~/javacode$ jcmd 6294 VM.set_flag MaxNewSize 1G
6294:
only 'writeable' flags can be set
Run Code Online (Sandbox Code Playgroud)
编辑:它适用于可管理的标志,下面是成功的命令.
XXXX@XXX-Air:~/javacode$ jcmd 11441 VM.flags -all | grep MinHeapFreeRatio
uintx MinHeapFreeRatio = 40 {manageable} {default}
XXXX@XXX-Air:~/javacode$ jcmd 11441 VM.set_flag MinHeapFreeRatio 45
11441:
Command executed successfully
XXXX@XXX-Air:~/javacode$ jcmd 11441 VM.flags -all | grep MinHeapFreeRatio
uintx MinHeapFreeRatio = 45
Run Code Online (Sandbox Code Playgroud) 我目前正在调查压缩类空间问题。我知道问题是什么,但在调查时,我注意到这一点jstat -gc ...,并jcmd ... GC.heap_info给出了不同数量的元空间和压缩类空间容量和使用情况:
\xe2\x96\xb6 jcmd 32152 GC.heap_info\n32152:\n PSYoungGen total 153600K, used 129316K [0x00000000eab00000, 0x00000000f5b00000, 0x0000000100000000)\n eden space 137728K, 91% used [0x00000000eab00000,0x00000000f26abf48,0x00000000f3180000)\n from space 15872K, 16% used [0x00000000f4100000,0x00000000f439d428,0x00000000f5080000)\n to space 15872K, 0% used [0x00000000f3180000,0x00000000f3180000,0x00000000f4100000)\n ParOldGen total 290816K, used 21446K [0x00000000c0000000, 0x00000000d1c00000, 0x00000000eab00000)\n object space 290816K, 7% used [0x00000000c0000000,0x00000000c14f1ac0,0x00000000d1c00000)\n Metaspace used 59690K, capacity 64980K, committed 65192K, reserved 1103872K\n class space used 9289K, capacity 10116K, committed 10152K, reserved 1048576K\n\n\xe2\x96\xb6 jstat -gc 32152\n S0C S1C S0U S1U …Run Code Online (Sandbox Code Playgroud) 我们正在监控 jvm 指标,如堆、元空间、线程和 gc 计数,我们能够将这些指标推送到监控服务器,如 prometheus。类似地,我们想跟踪 Java 本机内存指标(jcmd VM.sumary 的输出)。我的问题是,是否可以通过调用任何 jvm 运行时类来获取这些指标?
在使用jcmd监控java进程时,有一个命令ManagementAgent.start。
检查man page/oracle文档/google,没有找到任何描述。
问题是:
我尝试使用 jcmd(从 git bash 控制台窗口)进行堆转储:
$ /c/Program\ Files/Java/jdk1.8.0_202/bin/jcmd 25156 GC.heap_dump filename=livetest-grindtohalt.hprof
25156:
Heap dump file created
Run Code Online (Sandbox Code Playgroud)
但是,该文件似乎不存在:
$ find -name livetest-grindtohalt.hprof
$
Run Code Online (Sandbox Code Playgroud)
我在哪里可以找到它?
我想使用jmap或诊断一些意外的 OOM 错误jcmd。不幸的是,这些工具在 CI 管道中并不容易使用,因为我必须在后台启动 JVM 应用程序,以某种方式获取其 PID,然后获得正确的时间以使结果有用。
因此,我尝试从 JVM 应用程序启动它们,该应用程序将被诊断为 \xe2\x80\x94 程序化自拍。
\n在代码中的适当位置,我启动jmaporjcmd作为一个新进程:
val process = ProcessBuilder("jcmd", getPID(), "GC.class_histogram")\n .redirectOutput(ProcessBuilder.Redirect.PIPE)\n .redirectError(ProcessBuilder.Redirect.PIPE)\n .start()\n\nprocess.waitFor(2, TimeUnit.MINUTES)\nRun Code Online (Sandbox Code Playgroud)\n不幸的是,这两个工具的代码都挂起。系统监视器显示 JVM 应用程序和应用程序都jcmd在休眠。jcmd但是,当我在睡眠 JVM 上使用时:
jcmd 37058 GC.class_histogram\nRun Code Online (Sandbox Code Playgroud)\n我立即得到所需的直方图。
\n知道发生了什么事吗?
\njava ×8
jcmd ×8
jvm ×5
heap-dump ×1
heap-memory ×1
hprof ×1
java-8 ×1
java-9 ×1
jmap ×1
jstat ×1
linux ×1
metaspace ×1
monitoring ×1
prometheus ×1