Come serializzare grandi oggetti in .NET? (Eccezioni OutOfMemory)
-
22-08-2019 - |
Domanda
Sto usando la serializzazione per la funzione "salva" nella mia applicazione. Ma quando i dati è troppo grande (15+ MB) sto iniziando a ottenere eccezioni OutOfMemory.
Ho tanti oggetti e sono collegati con altri oggetti piccoli, credo che questo sta causando troppa potenza di elaborazione dati e tenuta in memoria.
Il mio codice si basa su questo, quasi lo stesso:
http://www.codeproject.com/KB/vb/TreeViewDataAccess.aspx
Modifica
-
Non faccio uso di serializzazione personalizzata, è tutto fatto da [serializzazione] attributi. Escludendo alcuni campi.
-
I serializzare tanti oggetti e classi personalizzate. Include Dictionary, strutture e mucchio di altre cose.
-
I serializzare in un file.
-
Io uso XmlSerializer
P.S. Ho 4 GB di memoria fisica.
Soluzione
Grazie alle risposte, il mio problema è risultato essere con XmlSerializer e devo liberarsi di esso. serializzazione binaria sta lavorando bene con i dati che ho.
Soluzione
15 MB non si dovrebbe dare un OOM.
Se i dati sono ad albero (piuttosto che un grafico completo), si potrebbe considerare un serializzatore come protobuf-net; così come usando molto efficiente binarie "buffer di protocollo" (sia la velocità e memoria) di Google formato, beneficia di non avere a che fare riferimento monitoraggio (necessario per grafici) - che significa che ha solo preoccuparsi di dati una volta (due volte se ne ha per essere tamponata).
Tuttavia, questo richiede markup diverso alle classi (o almeno, un "opt in") - e non gestirà i grafici completi. Ma è lì, e la connessione ...
Altri suggerimenti
Ho avuto esattamente lo stesso problema. La ragione è che .NET serializzazione non scala.
Ho risolto il problema utilizzando eccellente aperto di Simon Hewitt libreria sorgente, vedere Ottimizzazione serializzazione in .NET - parte 2 .
Oltre a ridurre drasticamente l'utilizzo della memoria è anche molto Più veloce. Simile a l'articolo che ho ricevuto un'accelerazione di 20 volte.
In realtà, XmlSerializer ignora il SerializableAttribute attributi. Sono utilizzati solo dalle classi di formattazione (BinaryFormatter, SoapFormatter).
Non vorrei serializzare utilizzando il XmlSerializer, e soprattutto non una combinazione di XmlSerializer e BinaryFormatter.
Vorrei semplicemente cercare di serializzare tutto utilizzando il BinaryFormatter.
Si potrebbe scrivere le proprie routine di serializzazione e vedere se è possibile ottenere tutti i benefici di prestazioni a mano-adattando il processo di serializzazione. Per maggiori dettagli, vedere la pagina MSDN su Custom serializzazione .
Forse ci può dare qualche dettaglio in più su come la serializzazione è fatto. Non si utilizza una serializzazione personalizzata? O ti basta usare l'attributo built-in [serializzazione]?
Credo che un buon modo per gestire questa situazione è di provare a fare la tua logica serializzazione personalizzata e solo serializzare solo quello che serve, non può andare a 4GB, in ogni caso dipende anche da quanto l'applicazione dispone di memeory assegnato.
Con tutti gli approcci che sono menzionati qui, la facilità di pratiche di dumping grandi oggetti su disco e il recupero è perduto. Anche questi sostegno discarica solo i tipi di dati, quindi non è possibile scaricare i tipi di riferimento facilmente come si potrebbe con BinaryFormatter.
fare anche la compressione utilizzando gzip o 7-Zip prima della formattazione binaria di oggetti di grandi dimensioni in realtà spostare la dimensione superiore a 16 MB a qualcosa come 32 MB.
Si potrebbe Scarica JSON.NET biblioteca che funziona nel mio progetto più di serializzazione e deserializzazione 100 MB di dati.
per la serializzazione si può lavorare come
Se si dispone di utilizzare l'oggetto TextWriter
using (TextWriter textWriter = File.CreateText("LocalJsonFile.json"))
{
var serializer = new JsonSerializer();
serializer.Serialize(textWriter , yourObject);
}
Se si dispone di uso stringa StringWriter
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using(JsonWriter textWriter = new JsonTextWriter(sw))
{
var serializer = new JsonSerializer();
serializer.Serialize(textWriter, yourObject);
}
Questo può funzionare per voi.