英文:
HeapDumpOnOutOfMemoryError doesn't dump heap when run inside docker container
问题
我正在一个Docker容器内运行一个Spring Boot服务,该服务的`POM.xml`文件中有以下插件:
<plugin>
<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日志进行的配置:
<Logger name="org.springframework" level="error" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile" />
</Logger>
因此,我可以看到日志被创建并转储到Docker容器中的/logs文件夹中,但我没有得到heapdump.bin文件。我将它放在logs文件夹中,因为这个文件夹被挂载在虚拟机上,因此我们可以从外部访问这个文件夹的内容。
有人能指出这里的问题吗?至少我需要GC日志来验证这个问题。
英文:
I am running a Spring Boot service inside a Docker container and the serivce POM.xml
file has this plugin
<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>
I see my service getting an OOM but I don't get the heapdump.bin
or the GC logs.
This is my configuration in log4j2.xml for springframework logs
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile" />
</Logger>
So I get the logs created and dumped into /logs folder in the Docker container, but I don't the heapdump.bin file. I am putting it in logs because this is mounted on VM, hence we can access this folder contents from outside access.
Can someone please point out the issue here? I at least need the GC logs to verify the issue.
答案1
得分: 3
(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参数传递给程序。
英文:
(JVM) arguments are not part of the JAR.
Eclipse even has a warning indicating this when you try to package an application with arguments to a JAR.
The JVM arguments in the spring-boot-maven-plugin
are for running the program using mvn spring-boot:run
.
If you want to execute a JAR with JVM arguments, run it by passing those using the command line:
java -XX:+HeapDumpOnOutOfMemoryError -jar yourjar.jar
If you don't want to write those arguments every time you run the program, you could create a wrapper script that just runs the java
command with the arguments.
If you really want the jvm arguments to be part of the JAR, you could create another main class (and specify that to be written to the MANIFEST.MF
) that just runs itself with the other main class and passes those arguments:
java -XX:+HeapDumpOnOutOfMemoryError -cp yourjar.jar fully.qualified.name.of.Main
However (depending on your needs), the program would need to redirect stdin
/stdout
, find out the path of the jar, find out the path of the java installation and also pass jvm arguments passed to itself to the program.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论