2
votes

Le processus Java à E / S élevées reçoit systématiquement le signal 11 SIGSEGV dans un JavaThread lorsqu'il est exécuté dans un conteneur Docker

Quelqu'un a-t-il pu reproduire de manière cohérente des SIGSEGV sur le JRE en utilisant différents matériels et différentes versions de JRE? Remarque (potentiellement importante): j'exécute le processus dans un conteneur Docker déployé sur Kubernetes.

Exemple d'erreur:

# 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]

Je gère actuellement un I Processus / O qui a de nombreux threads effectuant des E / S et de la sérialisation: téléchargement de CSV et JSON, lecture de CSV, écriture de JSON dans CSV et chargement de CSV dans MySQL. Je fais cela des milliers de fois pendant le cycle d'exécution de l'application. Je n'utilise que des bibliothèques couramment utilisées (Jackson, jOOQ) et du code "normal": en particulier, je n'ai pas écrit de code personnalisé utilisant le JNI.

Sans faute, la machine virtuelle Java SIGSEGV à chaque cycle d'exécution. Il semble SIGSERV dans diverses parties de la base de code, mais jamais sur un thread GC ou tout autre thread bien connu. Le "cadre problématique" est toujours du code compilé.

Spécifications de test:

  • Plusieurs instances matérielles différentes dans AWS.
  • Testé avec Java 8 191 et 181. Ubuntu 16.04.
  • Ce processus s'exécute dans un conteneur (Docker) et est déployé sur Kubernetes.
  • Version Docker: 17.03.2-ce

Voici le journal complet: https://gist.github.com/navkast/9c95f56ce818d76276684fa5bb9a68

>


0 commentaires

3 Réponses :


2
votes

À partir du journal complet:

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

Cela signifie qu'un kill () a été émis. Ce n'est pas un problème JVM. Quelque chose tue délibérément le processus. Probablement à cause d'un manque de mémoire.


1 commentaires

Réponse automatique, voir stackoverflow.com/a/54043383/3145261 et stackoverflow.com/a/54033261/3145261 pour décrire complètement pourquoi ce problème s'est produit. Merci pour votre réponse!



2
votes

D'après votre commentaire, il s'agit probablement d'un cas où les limites de votre conteneur sont inférieures à votre espace de tas + espace nécessaire pour GC.

Quelques informations sur la façon d'exécuter la JVM dans un conteneur ici .

Vous n'avez publié aucune spécification de pod, mais vous pouvez également consulter les limites de réglage de votre Pods Kubernetes .


1 commentaires

Vous avez raison, j'ai oublié de l'inclure. La limite de pod est très grande (32 Go), mais il s'avère qu'elle n'était pas assez grande en raison d'un chemin de code particulièrement pathologique. Merci pour votre réponse!



1
votes

Un gros indice est ici

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

Sur 32 Go, seul 1 Mo est libre au moment du crash. Très probablement, le processus a été tué car le système n'a plus de mémoire. Je suggère:

  • réduisant considérablement la taille du tas. par exemple. 2 à 8 Go
  • augmentation de la mémoire disponible. par exemple. 4 à 16 Go
  • ajout d'un espace d'échange. par exemple. 8 - 32 Go, cela ne résout pas le problème mais gérera la mémoire pleine avec un peu plus de grâce.


1 commentaires

Il s'avère que vous avez raison! De plus (selon ma réponse), le journal complet dit: siginfo: si_signo: 11 (SIGSEGV), si_code: 0 (SI_USER) (ce qui signifie qu'un kill () était émis. Consultez ma réponse personnelle: stackoverflow.com/a/54033060/3145261 )