2012-08-14 7 views
10

Qualcuno sa perché java 7 non riesce a raccogliere la generazione permanente di app, con conseguente java.lang.OutOfMemoryError: PermGen, mentre java 5 raccoglie la generazione permanente e le esecuzioni dell'app bene?Java 7 non riesce a raccogliere la generazione permanente che viene raccolta da java 5

App esegue la valutazione delle espressioni jython nel ciclo, una iterazione è di ca. 5 sec. corpo del ciclo appare come:

PythonInterpreter py = new PythonInterpreter(); 
py.set("AI", 1); 
((PyInteger)py.eval(expr)).getValue() 

Screenshots di jvisual vm presi per applicazione in esecuzione in Java 7 e Java 5.

In entrambi i casi vengono utilizzati gli stessi parametri:

-Xmx700m 
-XX:MaxPermSize=100m 
-XX:+HeapDumpOnOutOfMemoryError 
-Xloggc:"C:\Temp\gc.log" -XX:+PrintGCDetails -XX:-TraceClassUnloading -XX:+PrintClassHistogram 

java 7 java 5

+1

Hai controllato gli algoritmi gc accedendo a JConsole o qualche altro strumento? – kosa

+1

Potrebbero esserci impostazioni di avvio JVM diverse. C'è qualcosa di insolito nella tua applicazione? come codice di caricamento a caldo, caricatori di classi personalizzate ecc.? – Andy

+0

Le persone di GC stanno sempre modificando il GC, cercando disperatamente di migliorare le prestazioni, quindi non sono sorpreso che ci sia una tale differenza. La mia __guess__ è che ora sono focalizzati sul 700Mb piuttosto che sul 100Mb e stanno lasciando espandere la memoria permanente piuttosto che impiegare lo sforzo per controllarlo. Sono focalizzati sulle alte prestazioni e restano entro 700Mb piuttosto che buoni numeri per PermGen. – RalphChapin

risposta

0

Una possibilità per la perdita di permgen è l'interfaccia serializzabile asso implementato da ciascun PyInteger che viene memorizzato in una mappa statica class_to_type (PyType.java:101), questa è una Jython bug. Le uniche modifiche interessanti all'allocazione di permgen tra 5 e 7 di cui sono a conoscenza sono la rimozione di stringhe internate in 7 e alcune modifiche all'assegnazione diretta della memoria del buffer di byte, quindi il comportamento temporale del grafico potrebbe essere spiegato dallo unloading di tipi su ogni iterazione in Java 5.

2

Avendo un piccolo esempio per riprodurre il problema, ho trovato che il programma in esecuzione in java 7 all'esterno di Eclipse non soffre di perdite di memoria nella generazione permanente.

import org.python.core.PySystemState; 
import org.python.util.PythonInterpreter; 

public class Test01 { 

    public static void main(String[] args) throws Exception { 
    PySystemState.initialize(); 
    long startNanos = System.nanoTime(); 
    for(int i = 0; i < 450000; i++) { 
     PythonInterpreter pi = new PythonInterpreter(); 
     long elapsedNanos = System.nanoTime() - startNanos; 
     int avgStepInMicros = (int)((elapsedNanos/1000)/(i+1)); 
     final String code = String.format(
       "stepNo = %d + 1\n" + 
       "if stepNo %% 100 == 0:\n" + 
       " print 'stepNo: %%d, elapsedMillis: %%d, avgStepInMicros: %%d' %% (stepNo, %d, %d)", i, elapsedNanos/1000000, avgStepInMicros); 
     pi.exec(code); 
    } 
    } 
} 

MAT mostrato un filo debugger come root garbage collector.

GCRoot

strana è che Debug di applicazioni in Java 5 non ha questo problema.

+0

Il debugger si trova su tali riferimenti? Dannazione. – MilesHampson