Domanda

Abbiamo un programma java che richiede una grande quantità di spazio heap - lo iniziamo con (tra gli altri argomenti della riga di comando) l'argomento -Xmx1500m, che specifica uno spazio heap massimo di 1500 MB. Quando si avvia questo programma su una finestra di Windows XP che è stato appena riavviato, verrà avviato ed eseguito senza problemi. Ma se il programma è stato eseguito più volte, il computer è rimasto in funzione per un po ', ecc., Quando tenta di avviarsi ottengo questo errore:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Sospetto che Windows stessa soffra di frammentazione della memoria, ma non so come confermare questo sospetto. Nel momento in cui ciò accade, Task Manager e sysinternals procexp segnalano 2000 MB di memoria libera. Ho esaminato questa domanda relativa alla frammentazione interna

Quindi la prima domanda è: come posso confermare il mio sospetto? La seconda domanda è, se i miei sospetti sono corretti, qualcuno conosce qualche strumento per risolvere questo problema? Mi sono guardato un po 'in giro, ma non ho trovato nulla di utile, tranne i riavvii periodici della macchina.

ps - anche la modifica dei sistemi operativi non è attualmente un'opzione praticabile.

È stato utile?

Soluzione

D'accordo con Torlack, molto di questo è perché altre DLL vengono caricate e vanno in determinati punti, rompendo la quantità di memoria che puoi ottenere per la VM in un grosso blocco.

Puoi fare un po 'di lavoro su WinXP se hai più di 3G di memoria per spostare alcune delle cose di Windows, cerca PAE qui: http://www.microsoft.com/whdc/system/ piattaforma / server / PAE / PAEdrv.mspx

La tua scommessa migliore, se hai davvero bisogno di più di 1,2 G di memoria per la tua app java, è guardare Windows a 64 bit o Linux o OSX. Se stai usando qualsiasi tipo di libreria nativa con la tua app, dovrai ricompilarli per 64 bit, ma sarà molto più semplice che provare a riordinare dll e cose per massimizzare la memoria che puoi ottenere su finestre a 32 bit .

Un'altra opzione sarebbe quella di dividere il programma in più macchine virtuali e farle comunicare tra loro tramite RMI o messaggistica o qualcosa del genere. In questo modo ogni VM può avere un sottoinsieme della memoria di cui hai bisogno. Senza sapere cosa fa la tua app, non sono sicuro che questo possa aiutare in alcun modo, però ...

Altri suggerimenti

A meno che non si stia esaurendo lo spazio per i file di paging, questo problema non è che la memoria del computer è insufficiente. Il punto centrale della memoria virtuale è consentire ai processi di utilizzare più memoria virtuale di quanto sia fisicamente disponibile.

Non sapendo come JVM gestisce l'heap, è un po 'difficile dire esattamente quale sia il problema, ma uno dei problemi comuni è che non c'è abbastanza spazio di indirizzi libero contiguo disponibile nel processo per consentire l'heap da estendere. Perché questo sarebbe un problema dopo che la macchina è stata in esecuzione per un po 'è un po' confuso.

Ho lavorato su un problema simile al lavoro. Ho scoperto che eseguendo il programma usando WinDBG e usando l'indirizzo "! & Quot; e "! address -summary " i comandi sono stati preziosi per rintracciare il motivo per cui lo spazio di indirizzi virtuale di un processo è diventato frammentato. Puoi anche provare a eseguire il programma dopo il riavvio e usando "! Address " comando per scattare una foto dello spazio degli indirizzi e quindi fare lo stesso quando il programma non viene più eseguito. Questo potrebbe darti un'idea del problema. Forse qualcosa di semplice come una DLL aggiuntiva in fase di caricamento potrebbe causare il problema.

Sospetto che il problema sia la frammentazione della memoria di Windows. C'è un'altra domanda qui su StackOverflow chiamata Memoria massima Java su Windows XP che menziona utilizzando Process Explorer per esaminare la posizione in cui le DLL sono mappate nella memoria e quindi per risolvere il problema, ridisegnando le DLL in modo da caricarle in memoria in modo più compatto.

L'uso di Minimem ( http://minimem.kerkia.net/ ) per l'applicazione potrebbe risolvere il problema problema. Tuttavia, non sono sicuro che questa sia la risposta che stai cercando. Spero che sia d'aiuto.

Forse dovresti considerare di avviare il programma e riservare la memoria e non termina la VM dopo ogni esecuzione. Cerca diverse opzioni GC e rilascia i tuoi oggetti.

Usa vmmap dagli strumenti SysInternals di Microsoft per visualizzare la frammentazione dello spazio degli indirizzi virtuali e identificare cosa sta distruggendo lo spazio

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