java.lang.OutOfMemoryError: espace de classe compressé

Nous courons sur java-8-oracle.

Nous avons déménagé à Java8 il y a six mois.

Ces derniers jours, nous avons reçu un OOME de temps en temps et nous n’avons pas été en mesure d’identifier ou de reproduire le problème.

Lorsque nous exécutons un appel sur le serveur (tomcat), nous obtenons cette erreur sur le stacktrace:

java.lang.OutOfMemoryError: Compressed class space 

Le redémarrage du serveur résout le problème. Le même appel à un autre serveur fonctionne, ainsi qu’un autre appel d’un autre type au même serveur.

En regardant sur le gc.log, nous voyons:

 2015-05-27T16:05:42.991+0000: 98774.440: [Full GC (Last ditch collection) 98774.440: [CMS: 575745K->575330K(3495936K), 0.8687777 secs] 575745K->575330K(4107008K), [Metaspace: 97940K->97940K(1396736K)], 0.8696093 secs] [Times: user=0.95 sys=0.00, real=0.88 secs] 2015-05-27T16:05:55.486+0000: 98786.935: [Full GC (Metadata GC Threshold) 98786.935: [CMS: 573414K->578735K(3495936K), 0.9372859 secs] 925046K->578735K(4107008K), [Metaspace: 99428K->99428K(1396736K)], 0.9386626 secs] [Times: user=1.01 sys=0.00, real=0.94 secs] 

jstat -gc retourne:

  S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 87296.0 87296.0 0.0 3151.4 523776.0 148284.4 3495936.0 574868.5 1395640.0 98066.3 1048576.0 11339.1 12165 636.851 223 116.957 753.808 

Je ne vois aucun problème de mémoire dans le journal jstat ou dans le journal gc.

Essayer de lancer jmap -clstats bloque:

 Attaching to process ID 5110, please wait... Debugger attached successfully. Server comstackr detected. JVM version is 25.25-b02 finding class loader instances .. 

Nous avons été confrontés à un problème similaire. Malheureusement, heapdumps ne vous aidera pas car les classes ne sont pas dans le tas mais dans la mémoire native. Activez-les dans vos parameters JVM pour résoudre les problèmes liés aux classes chargées:

-XX: + PrintGCDetails -XX: + TraceClassUnloading -XX: + TraceClassLoading

Dans notre cas, le problème était que JAXBContext.newInstance n’était pas un singleton.

Bonne chance, Albert

Avec les oops et les pointeurs de classe compressés, l’espace disponible pour les classes est limité en raison de la nécessité de manipuler le pointeur. 1 Go dans votre cas.

Cela fait beaucoup de classes, cela pourrait donc indiquer que quelque chose dans votre application crée beaucoup de classes et ne les libère jamais. Reload application peut-être?

Si vous êtes certain que votre application a besoin de suffisamment de mémoire pour les classes, vous pouvez essayer de dépasser la limite via -XX:CompressedClassSpaceSize=... ou de désactiver les pointeurs de classe compressés via -XX:-UseCompressedClassPointers .

Notez que par défaut, l’espace de classe compressé + le tas compressé (+ quelques frais généraux) ne peut pas dépasser 32 Go. Bien que AIUI, la modification de l’alignement de l’object puisse dépasser cette limite.

Sinon, vous devriez prendre un tas de données et parsingr ce qui retient les classes chargées.