2015-01-22 11 views
18

È possibile che un'applicazione .NET 3.5 comunichi il runtime .NET: "hey, ho intenzione di utilizzare la memoria n in seguito, quindi per favore o commetti così tanto ora o fallisci ora? "Pre-allocare (garantire) la memoria in un'applicazione .NET

Il contesto per questo è: Ho un'applicazione console C# che esegue una query di database che restituisce molti dati e quindi esegue un'elaborazione su di esso. La query può richiedere molto tempo (ore) e l'utilizzo della memoria continua ad aumentare man mano che i risultati vengono letti. Al termine della query, è presente un picco immediato nella memoria a causa dell'elaborazione che devo eseguire. Se la macchina non ha abbastanza RAM, l'applicazione non riesce a quel punto - dopo aver perso ore sulla query! Questo è molto frustrante per l'utente. Se non c'è abbastanza RAM mi piacerebbe che l'applicazione fallisse rapidamente.

Ovviamente, potrei provare qualche hack come allocare un array di grandi dimensioni di cui non ho veramente bisogno e quindi impostarlo su null prima che abbia davvero bisogno della memoria, ma questo non è l'ideale, perché potrebbe effettivamente causare processo per esaurire la memoria quando altrimenti avrebbe abbastanza. Idealmente, mi piacerebbe non usare più memoria del necessario, ma semplicemente fallire presto a meno che non venga garantita una certa quantità per tutto il tempo in cui la mia applicazione funziona. È possibile?

+0

Sei sicuro che il trattamento è CPU-bound sui dati in memoria? Perché qualcosa richieda ore sembra che debba esserci anche un sacco di IO? – Enigmativity

+0

Quanto costa la quantità di dati recuperati dalla query in mb (intorno)? – ceztko

+2

Questo è un problema interessante, per essere sicuro. Potrebbe essere possibile memorizzare nella cache i risultati della query su memoria secondaria (disco) o su un database locale prima dell'elaborazione. Quindi, se qualcosa va storto, è possibile recuperare rapidamente dalla macchina locale. Solo un pensiero. – STLDeveloper

risposta

20

Si potrebbe provare a utilizzare la classe MemoryFailPoint:

try 
{ 
    using (new System.Runtime.MemoryFailPoint(20)) // 20 megabytes 
    { 
     ... 
    } 
} 
catch (InsufficientMemoryException) 
{ 
    ... 
} 
+1

Bel risultato. A questo punto, vorrei anche suggerire all'interrogante di mantenere i risultati della query e di eliminare qualsiasi connessione/interfaccia con il db. Dopo che i risultati possono essere ricaricati dalla memoria per assicurarsi che solo i dati recuperati siano in memoria e non ci siano altre cache interne. Anche il codice di elaborazione deve essere controllato per garantire che non vi siano perdite. – ceztko

+0

Questo sembra utile - grazie! MSDN dice "Il MemoryFailPoint non fornisce garanzie riguardo alla disponibilità a lungo termine della memoria durante la vita del cancello", quindi non è infallibile, ma è comunque promettente. – EM0

+0

Dopo averlo provato per un po ', ho trovato sfortunatamente troppo poco affidabile per essere di qualsiasi utilità pratica (per me). Spesso, il costruttore di MemoryFailPoint generava un'eccezione, ma l'elaborazione avrebbe comunque avuto esito positivo. Altre volte, MemoryFailPoint non lanciava, ma l'elaborazione avrebbe comunque esaurito la memoria. – EM0

Problemi correlati