2013-02-20 9 views
9

Ha senso continuare l'esecuzione dopo aver rilevato l'eccezione EOutOfMemory o ora l'heap o lo stack è corrotto con un'alta probabilità?L'eccezione EOutOfMemory è recuperabile?

Non intendo il caso di EOutOfMemory causato da un precedente danneggiamento della memoria dovuto a errori come la scrittura su un indirizzo jolly, intendo il codice corretto che chiama GetMem e prende EOutOfMemory.

+0

a volte lo è. Ho visto persone che cercavano di allocare 3GB di memoria buffer nelle app Win32 :-) Quindi dipende da cosa hai veramente provato a fare prima di ottenere l'errore. In alcuni casi è recuperabile. –

risposta

6

A mio parere, non ha senso il tentativo di continuare da EOutOfMemory. Nella mia esperienza, è possibile che le probabilità siano eccessivamente alte e che l'heap sia corrotto e che si possano prevedere errori futuri. Di solito, il modo più sicuro di agire è terminare il processo.

+0

Sospetto che non sia recuperabile, ma non ne sono sicuro. Non conosco i componenti interni di FastMM e forse la gestione della memoria di Windows. – kludg

+1

Nel nostro server rivendichiamo memoria all'inizializzazione rilasciata su EOutOfMemory in modo che l'eccezione e altre registrazioni abbiano spazio di manovra prima di interrompere il processo. –

+0

@ MarjanVenema Anche questo è rischioso, almeno se l'altro codice utilizzerà l'heap danneggiato. Notare che Delphi RTL alloca la singola istanza 'EOutOfMemory' all'avvio in modo che non sia necessario eseguire l'allocazione dell'heap per sollevare l'eccezione. –

1

In generale, sono d'accordo sul fatto che non abbia senso cercare di recuperare. Ma può essere utile in circostanze specifiche. Ad esempio, allocando grandi quantità di memoria che dipendono dalle scelte dell'utente e, in caso di errore, è possibile eseguire il backup in modo pulito e riprovare con impostazioni diverse. Lo faccio per convertire le nuvole di punti in mesh 3D, che include alcuni passaggi in cui i requisiti di memoria non sono noti in anticipo. Richiede solo un'attenta codifica dei passaggi che si desidera ripristinare, con un percorso di backout immediato e pulito. Ad esempio, alcune delle mie strutture dati sono bitmap o buffer con ogni riga allocata separatamente per ridurre al minimo i problemi con la memoria frammentata. I costruttori hanno provato ... tranne la gestione e l'emissione di un'eccezione EOutOfMemory, e i distruttori liberano qualsiasi riga già assegnata. Non posso garantire che funzionerà sempre, ma ha funzionato abbastanza bene da meritare di essere fatto.

Problemi correlati