2016-11-03 1 views
1

Nous avons une application Java déployable sur Swisscom Cloud. Instance ayant 1,5 G de RAM. Nous utilisons les paramètres suivants pour CF pour limiter l'utilisation de la mémoire pour cette application.L'application Java sur Swisscom Cloud échoue avec OOM

[jre: { version: 1.8.0_+ }, memory_calculator: {memory_sizes: {stack: 228k}, 
memory_heuristics: {heap: 50, metaspace: 20, native: 50, stack: 10}}] 

Sous exemple, lors de l'exécution ps -ef | grep java nous obtenons:

-Xms611500K -XX:MetaspaceSize=244600K -Xmx611500K -XX:MaxMetaspaceSize=244600K -Xss228 
-XX:MaxDirectMemorySize=256m -XX:InitialCodeCacheSize=32m -XX:ReservedCodeCacheSize=64m 
-XX:CompressedClassSpaceSize=250m -XX:+UseCompressedOops -XX:+UseCompressedClassPointer 

Malheureusement après un certain temps notre processus d'application est tué ("Sortie avec le statut 137"). Nous avons essayé différents autres paramètres pour CF, mais pas de chance. Malgré le fait que nous avons limité la mémoire utilisée, nous sommes toujours à court de 1,5 Go de RAM.

2016-11-10T14:31:08.34+0200 [API/0]  OUT App instance exited with guid 
72a197e9-e222-43b5-9828-9553c1d58315 payload: {"instance"=>"", "index"=>0, 
"reason"=>"CRASHED", "exit_description"=>"2 error(s) occurred:\n\n* 2 error(s) 
occurred:\n\n* Exited with status 137 (out of memory)\n* cancelled\n* cancelled", 
"crash_count"=>1, "crash_timestamp"=>1478781068233690142, 
"version"=>"ebfced51-9973-434b-8ec0-79a8caa86b3b"} 

Avant l'accident, nous avons analysé l'utilisation de la mémoire de tas en utilisant New Relic et ce que nous avons découvert que vous pouvez voir ci-dessous:

Used Heap memory Used Non-Heap memory Ici, autour de 04h30 est arrivé Exited with status 137 (out of memory). Comme vous pouvez le voir il n'y avait aucun dépassement de mémoire du tout.

Quand je commande top exécuté sous exemple cf avant l'accident, je suis arrivé à côté:

7 vcap 10 -10 6160764 1.357g 22528 S 27.3 7.4 3:09.52 java

Ce qui peut être fait de mal? Parce que je vois que le processus Java a effectivement utilisé près de 1,4 Go de RAM, mais à partir des graphiques New Relic, il n'y a pas une grande quantité de mémoire utilisée.

+0

Voir ici pour les codes de sortie: http://journal.thobe.org/2013/02/jvms-and-kill-signals.html Quand vous dites "... Malgré le fait que nous avons limité la mémoire utilisée ..." est-ce une limite dans cloudfoundry? Je suppose que cela tue votre processus s'il utilise trop de mémoire. Donc, vous devrez également limiter la mémoire dans JVM –

+0

Limiter la mémoire dans JVM en utilisant Xmx vous voulez dire? Oui j'ai limité ainsi. –

+0

J'ai ajouté plus de graphiques après la surveillance avec New Relic. –

Répondre

1

Je vais supposer que votre application se bloque car le conteneur CF pense qu'il utilise trop de mémoire. Cette hypothèse peut être validée en examinant les événements de crash dans "cf events" et en s'assurant qu'ils sont des plantages OOM. En supposant que c'est le conteneur qui plante l'application, c'est comme ça que je règle habituellement cette situation.

java_buildpack essaie vraiment de contenir l'utilisation de la mémoire d'une application. Cependant, il semble qu'il existe encore des applications où jvm trouve des moyens d'allouer de la mémoire en dehors des options configurées. Lorsque je rencontre ce problème, le moyen le plus simple pour régler la configuration est simplement de continuer à augmenter le taux de mémoire «natif» et de réduire le tas jusqu'à ce que l'application se stabilise. Native est le seau catch all pour tout ce que le jvm peut allouer que le buildpack ne gère pas. Je supprimerais également la configuration "heap: 600m" car cela ne ferait que compliquer les calculs heuristiques et potentiellement rendre inefficace le pourcentage natif croissant.

+0

Je seconde cette suggestion. Vous pourriez même envisager d'aller encore plus loin. Augmentez la limite de mémoire de votre application, mais ajustez le JBP de telle sorte qu'il n'augmente pas les limites d'espace de tas/méta. L'idée est de laisser une quantité ridiculement grande de mémoire "native" (vous pouvez l'agrandir plus tard), qui agit comme un tampon et donne à votre application une mémoire libre et inutilisée. Si vous l'augmentez suffisamment, cela empêchera votre application de tomber en panne et vous pourrez alors enquêter (jmap, profiler, etc.) qu'est-ce qui utilise plus de mémoire que ce que vous attendez dans votre application (ou peut-être la JVM). –

+0

Oh, assurez-vous également que vous utilisez JBP 3.8+. Certains ajustements ont été apportés aux calculs de la mémoire dans cette version. Si vous êtes bloqué sur une ancienne version, vous pouvez 'cf set-env JBP_CONFIG_OPEN_JDK_JRE [memory_calculator: {pile_threads: 300, taille_de_mémoire: {pile: 228k}, memory_heuristics: {tas: 65, natif: 15, pile: 10} }] ''pour obtenir les mêmes changements. –

+0

Actuellement je vais avoir la prochaine configuration: mémoire réservée par exemple CF - 1536m JBP_CONFIG_OPEN_JDK_JRE: [jre: {version: 1.8.0_ +}, {memory_calculator: memory_sizes: {pile: 228k}, memory_heuristics: {tas: 50, natif: 50, pile: 10}}] JAVA_OPTS: -XX: NativeMemoryTracking = détail -XX: MaxDirectMemorySize = 256m -XX: InitialCodeCacheSize = 32m -XX: ReservedCodeCacheSize = 64m -XX: CompressedClassSpaceSize = 150m -XX: + UseCompressedOops -XX : + UseCompressedClassPointers –