2012-03-21 14 views
10

Ho bisogno di testare alcuni script di monitoraggio JMX che ho sviluppato, In particolare, vorrei verificare che il mio monitoraggio della regione PermGen funzioni. Quindi, per testare questo mi piacerebbe essere in grado di eseguire un po 'di codice che carica un numero significativo di classi al fine di consumare PermGen.Riempire programmaticamente l'area di memoria JVM Permanent Generation (PermGen)

Il mio piano attuale è quello di scrivere uno script per generare prefix(1..n).java loro compilare e poi al momento giusto run:

for(int i=1 ; i < n ; i ++){ 
    Class.forName("com.mypackage.prefix"+i); 
} 

C'è una soluzione più elegante per raggiungere questo obiettivo?

+0

Penso che se si crea un'istanza di un nuovo ClassLoader e caricare la stessa classe più e più volte, sarà raggiungere il tuo obiettivo, senza la necessità di creare tonnellate di classi diverse. In alternativa, penso che String.intern() possa anche riempire il tuo spazio PermGen –

+0

@Guillaume: questa è una risposta, non un commento! –

+0

@ Tom, sì e no perché non ne sono sicuro, quindi questo è più un suggerimento. Non voglio sembrare affermativo su questo. ;-) –

risposta

10

OK, quindi sembra che String.intern() faccia il trucco. Ecco un'implementazione che ho trovato. Credits va a Gareth così:

public static void main(String[] args) throws ClassNotFoundException { 
    int i = 0; 
    StringBuilder sb = new StringBuilder("a"); 
    for (i = 0; i < 20; i++) { 
     sb.append(sb.toString()); 
    } 
    System.err.println(sb.length()); 
    i = 0; 
    Set<String> strings = new HashSet<String>(); 
    while (true) { 
     strings.add(sb.append(i++).toString().intern()); 
     System.err.println(i); 
    } 
} 
+0

Soluzione piacevole. Il bit che mi ha catturato la prima volta è che, a meno che tu non mantenga un riferimento alla stringa internata, il GC semplicemente svuota le stringhe da PermGen sul FullGC che alla fine forzerai. –