2015-06-30 13 views
6

Ho un List<Matrix4>, dove Matrix4 è una struttura contenente 16 float, quindi utilizza 16 * 4 byte = 64 byte.C# List <T> eccezione di memoria esaurita ma lontano dal limite di 2 Gb

Quando si aggiungono voci all'elenco, viene generata un'eccezione di memoria insufficiente quando si supera la linea da 1 milione.

So che .NET hanno un limite di 2 GB per oggetto, ma a meno che io sono completamente fuori di testa:

1.000.000 * 64 byte = ~ 61mb

che non è nemmeno vicino fino al limite.

Quando inizio a compilare l'elenco, in base al task manager, la mia applicazione utilizza 896mb e quando raggiungo l'eccezione utilizza 1028mb.

Il computer ha 8 GB di memoria fisica ma utilizza solo 6 GB.

Eventuali indizi sul perché potrebbe accadere?

--- UPDATE ----

modifica dell'obiettivo piattaforma x64 risolto il problema in un progetto di test separato. Sfortunatamente il progetto originale non può essere x64 i riferimenti dovuti alle DLL x86 che non funzionano su x64. Ma questo è un altro problema.

Non ho pensato di cambiarlo in x64 perché sembrava essere lontano dai limiti di memoria, ma immagino che Hans Passant avesse ragione a 122mb essendo troppo vicino al limite di 1,3 Gb. Grazie a tutti.

+5

Non è la risposta, ma non è possibile contare l'allocazione di memoria .NET in questo modo. –

+1

è necessario utilizzare gli strumenti in Visual Studio per profilare l'utilizzo della memoria. https://msdn.microsoft.com/en-us/library/dn342825.aspx –

+0

Non penso che sia la risposta anche. Ma ogni oggetto in .NET ha un'intestazione con informazioni. Nell'app a 32 bit l'intestazione è lunga 8 byte, nell'app 64 bit l'intestazione è lunga 16 byte. Quindi, OGNI float consuma 12 byte di lunghezza (nell'app a 32 bit). Senza vedere altro di codice è impossibile punto qual è il problema. –

risposta

11

Le grandi strutture vengono eseguite sull'Ohd (Large Object Heap) e sono soggette a frammentazione.

Quindi, mentre probabilmente hai abbastanza memoria libera, potresti non avere un blocco di memoria sufficientemente grande.

I tuoi numeri (1M x 64) non sono sufficienti da soli, solo con un numero sufficiente di altre allocazioni in corso spiegherebbe il problema. Potresti provare a risolvere questo particolare problema ma probabilmente è proprio il punto in cui un problema più grande diventa visibile.

In generale, TaskManager non è lo strumento giusto per diagnosticare problemi di memoria. Hai bisogno di un profiler di memoria per scoprire cosa sta succedendo.

Dipende anche dalla versione della piattaforma e dal fatto che sia 32 o 64 bit.

+0

Quale sarebbe la struttura grande qui? 'Matrix4' non è troppo piccolo per essere sul LOH? –

+1

@Asad - Sì, ma sono tipi di valore in modo che l'elenco <> conservi una matrice di byte Nx64. Con un grande N. –

+0

Ah, quindi anche singoli oggetti di grandi dimensioni possono essere allocati in blocchi attraverso il LOH (e quindi causare problemi di frammentazione)? –

Problemi correlati