在Docker容器中运行时,高I / O Java进程在JavaThread中始终获得信号11 SIGSEGV

时间:2019-01-03 23:21:44

标签: java docker kubernetes jvm

是否有人能够使用不同的硬件和不同的JRE版本在JRE上一致地复制SIGSEGV?注意(可能是一个大注意):我正在Kubernetes上部署的Docker容器中运行该过程。

示例错误:

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fea64dd9d01, pid=21, tid=0x00007fe8dfbfb700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_191-b12) (build 1.8.0_191-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.191-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# J 8706 C2 com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextFieldName()Ljava/lang/String; (493 bytes) @ 0x00007fea64dd9d01 [0x00007fea64dd9b60+0x1a1]

我目前正在管理一个高I / O流程,该流程具有许多执行I / O和序列化的线程:下载CSV和JSON,读取CSV,将JSON写入CSV以及将CSV加载到MySQL。在应用程序的运行周期中,我做了数千次。除了常用的库(Jackson,jOOQ)和“常规”代码外,我什么也没有使用:具体地说,我没有编写使用JNI的自定义代码。

在没有失败的情况下,JVM将在每个运行周期内进行SIGSEGV。在SIGSERV看来,代码库的各个部分都没有出现,但从未出现在GC线程或任何其他知名线程上。 “问题框架”始终是已编译的代码。

测试规格:

  • AWS中的多个不同硬件实例。
  • 使用Java 8 191和181测试。Ubuntu16.04。
  • 此过程正在容器(Docker)中运行并部署在Kubernetes上。
  • Docker版本:17.03.2-ce

这是完整的日志: https://gist.github.com/navkast/9c95f56ce818d76276684fa5bb9a6864

3 个答案:

答案 0 :(得分:2)

从完整日志中:

  

siginfo:si_signo:11(SIGSEGV),si_code:0(SI_USER)

这意味着发出了kill()。这不是JVM问题。某些事情在故意杀死进程。可能是由于内存不足。

答案 1 :(得分:2)

根据您的评论,这可能是您的容器限制低于堆空间+ GC所需空间的情况。

关于如何在容器here中运行JVM的一些见解。

您没有发布任何广告连播规范,但您也可以查看Kubernetes pods上的设置限制。

答案 2 :(得分:1)

一个大提示在这里

 Memory: 4k page, physical 33554432k(1020k free), swap 0k(0k free)

在发生故障时,32 GB中只有1 MB可用空间。由于系统内存不足,进程很可能被终止。我建议:

  • 显着减少堆大小。例如2-8 GB
  • 增加可用内存。例如4-16 GB
  • 添加一些交换空间。例如8-32 GB,这不能解决问题,但可以更优雅地处理全部内存。