2015-05-28 11 views
10

Siamo in esecuzione su java-8-oracle.java.lang.OutOfMemoryError: spazio classe compresso

Siamo passati a java8 sei mesi fa.

Negli ultimi giorni abbiamo ricevuto occasionalmente un OOME e non siamo stati in grado di identificare o riprodurre il problema.

Quando eseguiamo una chiamata al server (Tomcat) otteniamo questo errore sul stacktrace:

java.lang.OutOfMemoryError: Compressed class space 

Il riavvio del server risolve il problema. La stessa chiamata ad altri server funziona, e così fa un'altra chiamata di un altro tipo allo stesso server.

Quando si cerca sul gc.log vediamo:

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 rendimenti:

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 

non vedo alcun problema di memoria o nel jstat registro o nel registro gc.

Cercando di eseguire jmap -clstats si blocca:

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

Con quali interruttori Xms e Xmx si fa a lanciare la JVM? Ti consiglio di utilizzare visualvm o uno strumento simile per vedere meglio e imparare come sono configurate le dimensioni della tua JVM. O utilizzare Eclipse Memory Analyzer. Per ora puoi provare ad aumentare lo spazio delle classi compresse con -XX: CompressedClassSpaceSize. Per analizzare meglio il problema, è necessario impostare la JVM per eseguire il dump dell'archivio su OOME. – Marged

+0

Dopo quale periodo di tempo vedi questa eccezione? Hai provato ad aumentare il CompressedClassSpace? e.g: -XX: CompressedClassSpaceSize = 1g? Se vedi di nuovo il problema ma dopo un periodo di tempo più lungo sembra che ci sia una perdita di memoria di qualche tipo. –

+0

@DavidG - incontro per la prima volta 2 giorni fa in uno dei server (non abbiamo implementato la nuova versione). Riavvia il server e lo rivede dopo 12 ore in uno solo dei server. Dosnt carico stress non aiuta a riprodurre. La dimensione del comprimere rimane quasi la stessa e non è più simile a 1G, che è l'impostazione predefinita. – user1236097

risposta

5

Con oops compressi e compressi classe puntatori lo spazio a disposizione per le classi è vincolato a causa della necessaria puntatore mutilazione. 1 GB nel tuo caso.

Questo è un sacco di classi, quindi questo potrebbe indicare che qualcosa nella vostra applicazione sta creando molte classi e non le rilascia mai. L'applicazione può essere ricaricata?

Se si è certi che l'applicazione richiede solo molta memoria per le classi, è possibile provare a superare il limite tramite -XX:CompressedClassSpaceSize=... o disabilitare i puntatori di classe compressi tramite -XX:-UseCompressedClassPointers.

Nota che, per impostazione predefinita, lo spazio di classe compresso + heap compresso (+ un sovraccarico) non può superare 32 GB. Sebbene, AIUI, cambiare l'allineamento degli oggetti può aumentare ulteriormente tale limite.

Altrimenti dovresti fare un heapdump e analizzare cosa tiene sulle classi caricate.

+0

È possibile visualizzare nel registro jstat che CCSU è 1048576.0 e CCSU è 11339.1. – user1236097

+1

potrebbe essere la frammentazione? Non penso che lo spazio della classe venga compattato. Anche se un fattore così enorme è strano, anche se fosse una frammentazione. Inoltre, penso che sei fuori da una colonna, ancora, rimane una discrepanza. – the8472

+0

È possibile eseguire questo per vedere controllare se ho sbagliato in colonne: echo "S0C S1C S0U S1U CE UE OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT \ n 87.296,0 87.296,0 0,0 3.151,4 523.776,0 148.284,4 3.495.936,0 574.868,5 1.395.640,0 98.066,3 1.048.576,0 11.339,1 12165 636.851 223 116.957 753.808 "| colonna -t – user1236097

7

Abbiamo affrontato un problema simile. Sfortunatamente heapdump non ti aiuterà dato che le classi non sono nell'heap ma nella memoria nativa. Abilita questi nelle impostazioni JVM per risolvere le classi caricate:

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

Nel nostro caso la questione è stata JAXBContext.newInstance non essere Singleton.

Buona fortuna, Albert