2013-07-18 17 views
8

In una delle mie applicazioni VB.Net viene visualizzato un errore durante l'esecuzione dell'applicazione. Questo errore non viene sempre. Quindi non sono in grado di riprodurre anche l'errore. Nessuna sequenza esatta anche per riprodurre l'errore.OutOfMemoryException per un'applicazione vb.net

Stack: System.OutOfMemoryException: Memoria insufficiente. a System.Drawing.Graphics.FromHdcInternal (IntPtr HDC) a System.Windows.Forms.ToolStrip.OnPaint (PaintEventArgs e) a System.Windows.Forms.Control.PaintWithErrorHandling (PaintEventArgs e, strato di Int16, booleane disposeEventArgs) a System.Windows.Forms.Control.WmPaint (Messaggio & m) a System.Windows.Forms.Control.WndProc (Messaggio & m) a System.Windows.Forms.ScrollableControl.WndProc (Messaggio & m) presso System .Windows.Forms.ToolStrip.WndProc (Messaggio & m) a System.Windows.Forms.StatusStrip.WndProc (Messaggio & m) a System.Windows.Forms.Control.ControlNativeWind ow.OnMessage (Message & m) a System.Windows.Forms.Control.ControlNativeWindow.WndProc (Messaggio & m) a System.Windows.Forms.NativeWindow.Callback (IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

descrizione di errore:

MyApplication_UnhandledException

Dopo questo errore che ottengo un messaggio che dice,

0.123.

Memoria insufficiente per creare bitmap. Chiudi una o più applicazioni per aumentare la disponibilità.

Quando ho controllato l'utilizzo della memoria dell'applicazione non era così alto. Questo errore non appare ripetutamente. Quindi, come posso risolvere questo errore. Come può essere risolto? Ho controllato l'esecuzione dell'applicazione utilizzando. NET memory profiler e memoria Redgate Profiler.

Di seguito è riportato uno screenshot delle quantità di utilizzo della memoria non gestito. Non so bene se questi valori sono alti.

UPDATE:

ho ottenuto l'errore again.checked gli oggetti GDI ed era 9998.So l'errore è stato a causa della forte gdi objects.Now domanda è come solve.Then ho usato GDIView e controllato. Con quello strumento ho pen-2954 brush-5918 font-90 bitmap-13 ecc. GDI totale-9998 Allora, che cosa sono la penna e il pennello? Nel mio codice non ho usato pennelli o penne (ho cercato il codice per 'penna' e 'pennello' ma non ne ho trovate.) Quindi per favore aiutami su questo

+0

cosa si assegna a Tooltip? – Tigran

+1

Puoi mostrare il tuo codice, per favore? Preferibilmente una parte che funziona con le bitmap? – Ryan

+1

L'unica cosa ovvia è che si utilizzano i controlli ActiveX in modo piuttosto pesante. Il che può impedire al garbage collector di funzionare abbastanza spesso da tenerti lontano dai guai. Il tipo di problema che si verifica quando non si utilizza Dispose() sugli oggetti System.Drawing. Bombarda in questo modo quando hai usato troppe maniglie. –

risposta

8

Nel tuo Task Manager , vai al menu Visualizza per selezionare quali colonne mostrare nella scheda Processi. Seleziona che vuoi mostrare la colonna Oggetti GDI.Sono abbastanza certo che vedrai che gli oggetti GDI totali per il tuo processo stanno raggiungendo 10000, che è il massimo per qualsiasi processo.

Non si tratta della quantità di memoria fisica utilizzata. In questo senso, il messaggio di errore è molto povero e fuorviante. Il problema è che hai esaurito gli handle GDI. Ogni processo in Windows è limitato a un numero massimo di handle GDI che possono creare. Il limite è attualmente 10000 handle per processo.

Il motivo per cui suppongo che il problema sia l'handle GDI è perché l'eccezione viene generata quando si tenta di creare una nuova bitmap durante il processo di colorazione del controllo. Una bitmap è un oggetto GDI. La creazione di una bitmap utilizza un handle GDI per quella bitmap. Pertanto, questa è la causa più probabile.

Poiché l'errore si verifica nel controllo standard ToolStrip, è improbabile che si sia verificato un errore con lo ToolStrip stesso. È molto più probabile che tu sia, altrove nel tuo programma, utilizzando tutti gli handle GDI e poi, quando il controllo tenta di dipingersi, fallisce perché non ci sono maniglie rimaste.

Ogni volta che si creano oggetti GDI come penne e bitmap, è necessario assicurarsi di disporre di tali oggetti. Tutte le classi GDI che acquisiscono gli handle GDI implementano l'interfaccia IDisposable. Quando gli oggetti vengono eliminati, eliminano automaticamente le loro maniglie in quel punto. Ma se non si eliminano gli oggetti, le maniglie non vengono mai eliminate e il numero di oggetti GDI continuerà a crescere.

Per smaltire qualsiasi IDisposable oggetto, si può semplicemente chiamare il metodo Dispose quando si è fatto con l'oggetto, per esempio:

Dim b As New Bitmap("test.bmp") 
'... 
b.Dispose() 

Tuttavia, se è possibile, è ancora meglio per dichiarare le variabili per IDisposable oggetti con un blocco Using, come questo:

Using b As New Bitmap("test.bmp") 
    '... 
End Using 

con il blocco Using, il metodo Dispose verrà chiamato automaticamente per voi, quindi non è necessario chiamarlo esplicitamente da solo. Il motivo per cui il blocco Using è meglio che chiamare da solo Dispose perché, se viene generata un'eccezione all'interno del blocco Using, il metodo Dispose verrà comunque chiamato automaticamente. Se la chiami esplicitamente da solo, senza un blocco Using, è più facile perdere ogni posto che è necessario chiamarlo.

Per trovare l'area del problema nel codice, eseguire il programma nel debugger e scorrere il codice. Lascia il Task Manager aperto, mostrando la colonna GDI, mentre stai passando il codice. Guarda la colonna GDI nel Task Manager e vedrai aumentare il conteggio quando vengono creati nuovi oggetti GDI. Dovrebbe essere abbastanza facile, usando questo metodo, per vedere dove si trova il problema.

+1

+1 Come indicato, il blocco Utilizzo è l'ideale. –

+0

Verificherò l'oggetto gdi se ottengo errori in qualsiasi PC. –

+1

Durante il clic sulla griglia nella mia applicazione Msflexgrid non si stava disperdendo. Stava aumentando l'oggetto gdi per ogni clic sulla griglia e ottenuto la soluzione. Quindi ho risolto il problema eseguendo il programma in debugger. Ora il problema è risolto e ora il conteggio gdi rimane Da 250 a 300. Grazie mille. –

Problemi correlati