2015-05-14 16 views
5

Java suppone che non abbia perdite di memoria ma è ancora possibile. Quando il mio programma ha perdite di memoria, posso ripararlo (spero). Ma quando alcuni pacchetti di terze parti ce l'hanno, cosa posso fare? Praticamente nulla, tranne non usare questo pacchetto.Sandbox per memoria

C'è un'altra soluzione? Mi piace l'idea di sandbox. Sei autorizzato a fare tutto ciò che vuoi all'interno di una determinata area e tu "fisico" non hai la possibilità di disturbare altri fuori dalla tua scatola. C'è un modo per creare tale sandbox per l'utilizzo della memoria in Java? Immagina di creare sandbox per l'utilizzo della memoria, consentire a qualche pacchetto di fare quello che fa, ottenere risultati ed eliminare questa sandbox con tutto il resto della spazzatura qui! Nessuna complicanza con GC, nessuna pulizia o disposizione della memoria. Basta cancellare e dimenticarsene.

C'è un modo per farlo?

risposta

1

Il modo migliore è quello di avviare un'altra JVM, comunicare con essa con il socket (ad esempio) e uccidere la JVM dopo che è stata eseguita.

Sarebbe interessante discutere se possiamo eseguire il sandbox all'interno della stessa JVM.

Dopo aver terminato di utilizzare la libreria di terze parti e non si fa più riferimento a nessun oggetto da quella libreria, quale potrebbe essere la spazzatura che è ancora in sospeso?

  1. Le loro classi - anche se non si è referening nessuno di loro, se sono caricati con lo stesso classloader il tuo codice, queste classi persisteranno. E i loro campi statici potrebbero riferimento più dati persistente, e così via

  2. ThreadLocal - avrebbe potuto impostare alcune variabili locali filo, e non li ripulito

  3. Discussione - avrebbe potuto generato alcune discussioni che persistono

  4. In qualche luogo globale, ad es. System.setProperty() - rimarrà lì.

Quindi, in generale, è probabilmente difficile.

Tuttavia, nella maggior parte dei casi, è possibile utilizzare un classloader separato e un thread separato per eseguire la libreria di terze parti e questa strategia può probabilmente scaricare tutti i gavoni creati dalla parte terza.

Esistono strumenti per farlo? Non ne sono troppo informato. Ho qualche esperienza con l'implementazione di un server hot reloadable, e ho alcune classi di utilità che possono essere utilizzate per questo scopo. Per esempio

// wrap 3rd party code, expose it as some java.*.* interface 
public class MyWrapper implements Callable<String> 
{ 
    @Override 
    public String call() 
    { 
     return ThirdParty.query(..); 
    } 
} 



HotReloader hot = new HotReloader(); 
Callable<String> func = (Callable<String>)hot.getAppInstance("pkg.MyWrapper"); 
String result = func.call(); 
// then dereference `hot` and `func` 

vedere HotReloader

+0

Questo è buona idea, ma un po 'costoso. Potete immaginare di iniziare una nuova JVM per ogni richiesta di database? Una volta ero in conferenza JavaOne sulla presentazione di Plumbr "Scommetto che hai una perdita di memoria" e un paio dei loro esempi riguardavano la perdita di memoria nei driver di database standard. Era MySql se non mi sbaglio. –

+0

È possibile utilizzare ClassLoaders per isolare le classi problema. Quindi per ripulire la memoria utilizzata dalla libreria è sufficiente rimuovere tutti i riferimenti alle sue classi e al loader. Puoi anche usare un ThreadGroup separato per isolare i thread delle librerie, permettendoti di eliminarli facilmente. –

+0

@IzoldTytykalo: è possibile utilizzare una JVM per 2 richieste database :) o altro. – ZhongYu