Springboot应用程序在Cloud Foundry上崩溃而没有任何崩溃日志

时间:2019-09-26 22:26:08

标签: java spring-boot cloudfoundry jvm-crash

我有一个Spring Boot应用程序,该应用程序在Cloud Foundry上崩溃,没有明显的崩溃日志。该应用程序有3个实例,三个实例中的任何一个每天两次崩溃,两天一次崩溃。没有为崩溃定义的模式。

我尝试添加以下Java参数,并带有上述结果: -XX:ErrorFile:错误时未创建任何文件 -XX:+ HeapDumpOnOutOfMemoryError:实例崩溃时会创建堆转储。

实例崩溃但没有OOM日志时会创建堆转储。

我还尝试为Spring Boot应用程序添加嵌入式的tomcat日志,并添加了以下软件包: org.apache.tomcat,org.apache.catalina,org.apache.coyote。尝试在docker本地创建OOM,并可能看到OOM日志即将出现在应用程序的tomcat日志中。

只需澄清一下,问题是如何找到负责OOM的内存部分?

2 个答案:

答案 0 :(得分:0)

默认情况下,堆转储在VM的工作目录中的一个名为java_pidpid.hprof的文件中创建。您可以使用-XX:HeapDumpPath =选项指定备用文件名或目录。 有关Java紧急停止设置,请参见https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/clopts001.html

答案 1 :(得分:0)

在Cloud Foundry上运行Java应用程序时,使用-XX:+HeapDumpOnOutOfMemoryError将无济于事。添加该选项将触发堆转储,但它将被写入您的应用容器中。完成后,容器将消失,您将无法获取已写入的文件。

要使它在Cloud Foundry上工作,Java buildpack提供了一些帮助。

  1. 已添加到JVM的Java buildpack configures a killagent。发生OutOfMemoryError时,将执行此代理。它将打印内存使用情况的直方图,还将打印内存摘要。您将在cf logs的输出中看到这些。

    例如:

    Resource exhaustion event: the JVM was unable to allocate memory from the heap.
    ResourceExhausted! (1/0)
    | Instance Count | Total Bytes | Class Name                                    |
    | 18273          | 313157136   | [B                                            |
    | 47806          | 7648568     | [C                                            |
    | 14635          | 1287880     | Ljava/lang/reflect/Method;                    |
    | 46590          | 1118160     | Ljava/lang/String;                            |
    | 8413           | 938504      | Ljava/lang/Class;                             |
    | 28573          | 914336      | Ljava/util/concurrent/ConcurrentHashMap$Node; |
    

     Memory usage:
       Heap memory: init 65011712, used 332392888, committed 351797248, max 351797248
       Non-heap memory: init 2555904, used 63098592, committed 64815104, max 377790464
    Memory pool usage:
       Code Cache: init 2555904, used 14702208, committed 15007744, max 251658240
       PS Eden Space: init 16252928, used 84934656, committed 84934656, max 84934656
       PS Survivor Space: init 2621440, used 0, committed 19398656, max 19398656
       Compressed Class Space: init 0, used 5249512, committed 5505024, max 19214336
       Metaspace: init 0, used 43150616, committed 44302336, max 106917888
       PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936
    

    在Cloud Foundry上使用Java buildpack运行时,所有Java应用程序都会获得此信息,它有助于了解应用程序崩溃时的内存使用情况。如果您没有看到此消息,则您的应用由于其他原因崩溃(请参见下文)。

  2. 如果需要更多有关内存使用情况的信息,则可以获取完整的堆转储。为此,您需要将持久性存储绑定到您的应用程序。如果将卷服务绑定到应用程序,其中服务的名称包含heap-dump,则Java buildpack会将此存储设置为自动用于捕获堆转储。

      

    如果将名称或标签中包含字符串heap-dump的Volume Service绑定到应用程序,则将以<CONTAINER_DIR>/<SPACE_NAME>-<SPACE_ID[0,8]>/<APPLICATION_NAME>-<APPLICATION_ID[0,8]>/<INSTANCE_INDEX>-<TIMESTAMP>-<INSTANCE_ID[0,8]>.hprof模式编写终端堆转储


如果您没有看到JVM killagent的输出,或者没有看到生成到持久性存储的堆转储,则

  1. 检查是否已添加JVM代理。当构建包在过渡期间运行时,您应该会看到killagent已下载并安装。
  2. 它也应该显示在Java buildpack生成的启动命令中。检查启动命令以确保您看到代理。请注意,如果您使用cf push -c指定自己的启动命令,则buildpack将无法添加代理。
  3. 您只是没有遇到OutOfMemoryError。您的应用可能因其他原因崩溃。最常见的情况是您超出了容器的内存限制,而不是JVM的内存限制。在这种情况下,容器将立即崩溃,并且您将不会从killagent获得输出。

希望有帮助!