问题描述
我正在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参数传递给程序本身。