当 运行 在 docker 容器中时,HeapDumpOnOutOfMemoryError 不会转储堆

HeapDumpOnOutOfMemoryError doesn't dump heap when run inside docker container

我是 运行 Spring 一个 Docker 容器内的启动服务,服务 POM.xml 文件有这个插件

                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>
                        -Xms1024m
                        -Xmx3096m
                        -XX:+UseConcMarkSweepGC
                        -XX:+HeapDumpOnOutOfMemoryError
                        -XX:HeapDumpPath=logs/heapdump.bin
                        -XX:+PrintGCDetails
                        -Xloggc:logs/data-pipeline-automation-gc.log
                        -XX:NativeMemoryTracking=summary
                        -XX:+CrashOnOutOfMemoryError
                        -XX:ErrorFile=logs/crashDump.log
                    </jvmArguments>
                </configuration>
            </plugin>

我看到我的服务发生 OOM,但我没有收到 heapdump.bin 或 GC 日志。 这是我在 log4j2.xml 中针对 springframework 日志

的配置
            <AppenderRef ref="Console" />
            <AppenderRef ref="RollingFile" />
        </Logger>

所以我创建了日志并将其转储到 Docker 容器中的 /logs 文件夹中,但我没有 heapdump.bin 文件。我将它放在日志中,因为它安装在 VM 上,因此我们可以从外部访问访问此文件夹内容。

有人可以指出这里的问题吗?我至少需要GC日志来验证问题。

(JVM) 参数不是 JAR 的一部分。

当您尝试将带有参数的应用程序打包到 JAR 时,Eclipse 甚至会发出警告来指示这一点。

spring-boot-maven-plugin 中的 JVM 参数用于 运行使用 mvn spring-boot:run 的程序。

如果您想使用 JVM 参数执行 JAR,运行 通过使用命令行传递这些参数:

java -XX:+HeapDumpOnOutOfMemoryError -jar yourjar.jar

如果您不想每次 运行 程序时都写这些参数,您可以创建一个包装器脚本,它只是 运行 带有参数的 java 命令.

如果您真的希望 jvm 参数成为 JAR 的一部分,您可以创建另一个主 class(并指定将其写入 MANIFEST.MF)只是 运行s 本身与其他主要 class 并传递这些参数:

java -XX:+HeapDumpOnOutOfMemoryError -cp yourjar.jar fully.qualified.name.of.Main

但是(根据您的需要),程序需要重定向stdin/stdout,找出jar 的路径,找出java 的路径安装并将传递给自身的 jvm 参数传递给程序。