Ich bin auf der Suche nach einer Möglichkeit, eine große 3d-Sparse-Array-Struktur im Speicher zu halten, ohne viel Speicher zu verschwenden. Hier habe ich ein Experiment mit Arrays von Longs gemacht:
%Vor%Wenn Sie es testen möchten, setzen Sie die Umgebungsvariable COMPlus_gcAllowVeryLargeObjects (Projekteigenschaften - & gt; Debug) auf 1 oder ändern Sie die JMAX. Und das ist die Ausgabe:
%Vor%Wenn ich sehe, ist der Speicherverbrauch im Task-Manager in Process.WorkingSet64 so. Was ist die wahre Zahl? Warum wird Speicher auf Zuweisung zugewiesen? Ist ein Array tatsächlich ein kontinuierlicher Speicher? Ist ein Array ein Array? Existieren Aliens? (dramatische Hintergrundmusik)
Episode 2: Wir machen eine kleine Veränderung:
%Vor%und nichts ändert sich (in der Ausgabe). Wo ist der Unterschied zwischen existent und nicht existent? (mehr dramatische Hintergrundmusik) Jetzt warten wir auf die Antwort von einem der mysteriösen Menschen (Sie haben eine Nummer und ein kleines 'k' unter ihren Namen).
Folge 3: Eine weitere Änderung:
%Vor%Die Ausgabe:
%Vor%PMS64 für ein Array (15369-8) / 4 = 3840 MB Dies ist kein Sparse-Array, sondern ein teilweise gefülltes Array;). Ich benutze diese 168 MB voll.
Beantworten Sie einige Fragen "Warum verwenden Sie nicht die genaue Größe?". Weil ich es nicht weiß? Die Daten können aus mehreren benutzerdefinierten SQL-Dateien stammen. "Warum ändern Sie nicht die Größe?". Resize erstellt ein neues Array und kopiert die Werte. Dies ist die Zeit zu kopieren, Erinnerung und am Ende kommt der böse GC und isst dich.
Habe ich meine Erinnerungen verschwendet? (Ich erinnere mich nicht. Die Aliens ?!) Und wenn ja, wie viel? 0, (3840-168) MB oder (15369-8-168) MB?
Epilog:
Ist ein Kommentar ein Kommentar oder eine Antwort?
ist zusammenhängender Speicher tatsächlich zusammenhängender Speicher?
Antworten Antworten? Geheimnisvoll. ( mehr Musik )
( Scully : Mulder, Kröten sind einfach vom Himmel gefallen! Mulder : Ich denke ihre Fallschirme haben sich nicht geöffnet.)
Danke euch allen!
Der Arbeitssatz ist nicht die Menge des zugewiesenen Speichers. Es sind die Seiten, die derzeit für den Prozess verfügbar sind. Windows implementiert verschiedene Richtlinien und die Zahl ist im Allgemeinen schwer zu interpretieren.
Hier wurde der Speicher wahrscheinlich vom Betriebssystem auf Null gesetzt. Der erste Zugriff auf eine Seite macht tatsächlich eine nullte Seite verfügbar.
Sie sollten sich private Bytes ansehen.
Sie können .NET-Arrays nicht spärlich zuordnen. Wahrscheinlich sollten Sie eine Datenstruktur verwenden, die den Eindruck eines spärlichen Arrays vermittelt.
Ist ein Array tatsächlich ein fortlaufender Speicher?
Ja, aus der Sicht der CLR und des laufenden .NET-Codes. Das Betriebssystem kann jedoch Tricks spielen, wie z. B. langsam Fehler in den Seiten beim ersten Lesen oder Schreiben.
Bei "Episode 2" lautet die Antwort, dass der Fehler sowohl beim Lesen als auch beim Schreiben auftritt. Ich folge nicht ganz, was Episode 3 tut, aber ich nehme an, es berührt nur weniger Seiten.
Habe ich meine Erinnerungen verschwendet?
Das ist komplizierter zu sagen. Solange die Seiten nicht berührt werden, werden sie nicht physisch benutzt. Sie können zum Beispiel für den Dateicache oder für andere Programme verwendet werden, die resident arbeiten. Sie zählen jedoch auf die Commit-Gebühr des Systems. Windows garantiert Ihnen, dass Sie diese Seiten für Sie verfügbar machen können. Bei einem wahlfreien Speicherzugriff wird Ihnen nicht mehr genügend Arbeitsspeicher zur Verfügung stehen. Linux garantiert das nicht. Es hat den OOM-Killer als Mitigation.
Im Extremfall, wenn Sie 1TB so zuweisen, müssen Sie die Summe aus RAM und der Größe der Auslagerungsdatei auch 1 TB überschreiten, auch wenn dieser Speicherplatz möglicherweise nicht verwendet wird.
Erwägen Sie die Verwendung von Speicherabbilddateien. Hier ist die Datei der Sicherungsspeicher und RAM wird wie ein Cache behandelt. Dies würde sich genau so verhalten.
Tags und Links arrays c# .net-core-rc2