Domanda

Ho un ciclo che genera un sacco di fili. Questi fili contiene, tra le altre cose, 2 (massicci) oggetti StringBuilder. Questi fili poi correre e fare le loro cose.

Tuttavia, ho notato che dopo un certo periodo di fili, ricevo strani incidenti. So che questo è a causa di questi StringBuilder, perché quando ho ridurre la loro capacità iniziale, posso iniziare molto più thread. Ora, per questi StringBuilders, vengono a creare in questo modo nel costruttore dell'oggetto filo:

StringBuilder a = new StringBuilder (30000);
StringBuilder b = new StringBuilder (30000);

Il punto in cui si arresta generalmente è di circa 550 fili, che si traduce in un po 'più di 62MB. In combinazione con il resto del programma la memoria in uso è più probabile 64 MB, che ho letto da qualche parte on-line è stata la dimensione defaulf del pool di allocazione di memoria JVM. Non so se questo sia vero o meno.

Ora, c'è qualcosa che sto facendo male, che in qualche modo a causa del disegno, sto allocazione di memoria nel modo sbagliato? O è questo l'unico modo e dovrei dire alla JVM per aumentare il suo pool di memoria? O qualcosa di completamente diverso?

Inoltre, per favore non mi dica di impostare una capacità inferiore, so che questi StringBuilders aumentano automaticamente la loro capacità quando necessario, ma mi piacerebbe avere una soluzione a questo problema.

Altri suggerimenti

Se si memorizza un sacco di informazioni in uno StringBuilder, hai intenzione di riferimento di nuovo esso ad un certo punto? Se poi non basta scrivere su un altro supporto (DB, file etc). Il programma dispone di una quantità limitata di risorse, non può contenere tutti lo stato di un intero sistema in una volta. -Xmx vi darà più spazio per l'archiviazione nella memoria, ma non farà la vostra capacità di memorizzazione infinita.

Si consiglia di utilizzare un ThreadPoolExecutor, e impostare la dimensione del pool per il numero di CPU sulla vostra macchina. Creare più thread di CPU è solo aggiungendo ambientale.

ExecutorService service = Executors.newFixedThreadPool(cpuCount))

Inoltre, è possibile ridurre l'utilizzo della memoria scrivendo le stringhe in file invece di tenerli in-memory con StringBuilders.

Si supponga 1 MB per thread. Questo è il costo di RAM creando ciascuna, oltre la memoria allocata dal suo processo.

Come ha detto Gregory, dare la JVM, alcune opzioni come -Xmx.

È inoltre possibile utilizzare un ThreadPool o esecutore per garantire che solo una determinata quantità di fili sono accesi contemporaneamente. In questo modo la quantità di memoria può essere mantenuto limitato senza rallentamento (come il processore non è in grado di funzionare 550 fili allo stesso tempo comunque).

E quando si utilizza un esecutore non creare le StringBuilders nel costruttore, ma nel metodo di esecuzione.

È possibile utilizzare un FileWriter al testo di output in un file, quindi tirare indietro con un FileReader. In questo modo avrete solo bisogno di memorizzare il nome del file in memoria, piuttosto che l'intero contenuto della stringa.

Per ridurre le discussioni è possibile utilizzare un ExecutorService, o semplicemente usare qualche filo che leggono da una coda.

La mia ipotesi è che con un po 'di ritocchi probabilmente si può ottenere il vostro programma fino a non aver bisogno di molta memoria a tutti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top