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

问题描述

我正在Docker容器中运行Spring Boot服务,并且秘密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的一部分,则可以创建另一个主类(并指定要写入MANIFEST.MF),该主类仅与另一个主类一起运行并传递这些主类参数:

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

但是(取决于您的需求),程序将需要重定向stdin / stdout,找出jar的路径,找出Java安装的路径并传递jvm参数传递给程序本身。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...