2010-03-12 17 views
8

sto cercando di diagnosticare questa eccezione:System.Runtime.InteropServices.COMException (0x80070008): Memoria insufficiente è disponibile per elaborare questo comando

System.Runtime.InteropServices.COMException (0x80070008): Not enough storage is available to process this command. (Exception from HRESULT: 0x80070008) 
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType) 
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(Type objectType) 
at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(Type serverType) 
at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(Type serverType, Object[] props, Boolean bNewObj) 
at Oracle.DataAccess.Client.CThreadPool..ctor() 
at Oracle.DataAccess.Client.OracleCommand.set_CommandTimeout(Int32 value) 
... 

Non sembra come uno qualsiasi dei normali tipi di " stoccaggio "hanno raggiunto qualsiasi limite. L'applicazione utilizza circa 400 MB di memoria, 70 thread, 2000 maniglie e il disco rigido ha molti GB gratuiti. La macchina esegue Windows 2003 Enterprise Server a 32 bit con 16 GB di RAM, quindi la memoria non dovrebbe essere un problema.

L'applicazione è in esecuzione come servizio Windows, pertanto non vengono utilizzati oggetti GDI. L'esaurimento degli handle GDI è una causa comune di questa eccezione.

Connessioni database, comandi & i lettori sono tutti avvolti con l'utilizzo di blocchi in modo che dovrebbero essere puliti correttamente.

UPDATE: La riduzione del numero di thread che stavamo utilizzando da 12 a 4 sembra aver risolto il problema. Siamo riusciti a correre senza errori per oltre 24 ore, prima che durassimo tra le 4 e le 8 ore. UPDATE2: Non ho mai capito quale risorsa stavamo esaurendo, ma la riduzione del numero di thread sembra aver risolto il problema. O almeno lo nascose.

+1

È un processo a 64 bit? – SLaks

+0

Girato nel buio (vedi interop) stai chiamando Marshal.ReleaseComObject? –

+1

@ Marvin: l'interoperabilità viene eseguita da Oracle. – SLaks

risposta

0

Sembra che qualcosa stia eseguendo un ciclo e istanziando troppi oggetti nell'heap in modo da esaurire la memoria nell'heap. Cerca eventuali loop nel codice chiamante.

+0

In realtà dimenticarlo, Googling fa sembrare che questo sia un problema di memoria Oracle su macchine a 32 bit, quindi dubito di poterti aiutare al momento. –

6

Un altro fattore da considerare è la frammentazione della memoria.

L'allocazione singola massima che è possibile eseguire è uguale al più grande blocco di memoria contiguo disponibile per il processo. Questo è quasi sempre inferiore alla quantità totale di memoria disponibile nel processo a causa della frammentazione. Questo è assegnato blocchi di memoria seduti tra 2 blocchi liberi di memoria "frammenta" lo spazio.

Più frammentazione si ha nel processo, più piccolo è il più grande blocco di memoria contiguo che sarà disponibile. Ho visto situazioni in cui c'era circa 1 GB di memoria libera, ma il più grande blocco contiguo era di circa 10 MB.

Avete controllato la frammentazione della memoria in questo processo?

+0

Qualche consiglio su come rilevare la frammentazione della memoria? Attualmente sto provando il rilevamento delle perdite di memoria di DebugDiag sul processo in esecuzione su un server di prova. –

+0

La frammentazione non sembra essere un problema, il blocco libero più grande era 500 MB mentre l'applicazione stava avendo problemi. Questo è stato raccolto usando lo strumento vmMap di sysinternals. –

2

Hai eliminato tutte le cause ovvie di questo errore per il tuo processo. Rende probabile che questo sia in realtà un problema del sistema operativo. L'unica risorsa che è sempre sotto pressione su un server è il pool di memoria del kernel. È facile da vedere, TaskMgr.exe lo visualizza nella scheda Prestazioni.

In qualche modo corrisponde allo stack delle chiamate, sembra che il provider Oracle stia creando thread per un pool di thread. Un thread richiede un megabyte nel processo e 24 KB nel pool di memoria del kernel, utilizzato come stack quando il thread passa alla modalità kernel.

Informazioni di base è available here.

+0

Questo non sembra essere il problema in quanto vi sono oltre 40 MB di pool non di pagine libere e 100 MB di pool di paging. Ho anche guardato i contatori perfmon per tutti i semafori di eventi "Objects" ecc. E sembra che non ci siano perdite di questi. –

+0

Bene, è ora di dare una chiamata a Oracle. –

Problemi correlati