Ich bin auf der Suche nach einer Möglichkeit, große 3d Sparse Array-Struktur in den Speicher zu halten, ohne viel Speicher zu verschwenden. Hier habe ich ein Experiment mit Arrays von longs getan:Wie reserviert ein großes Array Speicher?
using System;
using System.Diagnostics;
using System.Runtime;
namespace ConsoleApp4
{
public class Program
{
static Process proc = Process.GetCurrentProcess();
const int MB = 1024 * 1024;
const int IMAX = 5;
const int JMAX = 100000000;
public static void ShowTextWithMemAlloc(string text)
{
proc.Refresh();
Console.WriteLine($"{text,-30}WS64:{proc.WorkingSet64/MB,5}MB PMS64:{proc.PrivateMemorySize64/MB,5}MB");
Console.ReadKey();
}
public static void Main(string[] args)
{
Console.Write(" ");
ShowTextWithMemAlloc("Start.");
long[] lArray = new long[IMAX * JMAX];
long[] l1Array = new long[IMAX * JMAX];
long[] l2Array = new long[IMAX * JMAX];
long[] l3Array = new long[IMAX * JMAX];
ShowTextWithMemAlloc("Arrays created.");
lArray[IMAX * JMAX - 1] = 5000;
l1Array[IMAX * JMAX - 1] = 5000;
l2Array[IMAX * JMAX - 1] = 5000;
l3Array[IMAX * JMAX - 1] = 5000;
ShowTextWithMemAlloc("Last elements accessed.");
for (var i=IMAX-1; i>= 0; i--)
{
for (var j=0; j<JMAX; j++)
{
lArray[i * JMAX + j] = i * JMAX + j;
}
ShowTextWithMemAlloc($"Value for row {i} assigned.");
}
//lArray = new long[5];
//l1Array = null;
//l2Array = null;
//l3Array = null;
//GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
//GC.Collect();
//ShowTextWithMemAlloc($"GC.Collect done.");
ShowTextWithMemAlloc("Stop.");
}
}
}
Wenn Sie testen wollen, es stellen Sie die COMPlus_gcAllowVeryLargeObjects Umgebungsvariable (Projekteigenschaften -> Debug) auf 1 oder die JMAX ändern. Und dies ist die Ausgabe:
Start. WS64: 14MB PMS64: 8MB
Arrays created. WS64: 15MB PMS64:15360MB
Last elements accessed. WS64: 15MB PMS64:15360MB
Value for row 4 assigned. WS64: 779MB PMS64:15360MB
Value for row 3 assigned. WS64: 1542MB PMS64:15360MB
Value for row 2 assigned. WS64: 2305MB PMS64:15361MB
Value for row 1 assigned. WS64: 3069MB PMS64:15361MB
Value for row 0 assigned. WS64: 3832MB PMS64:15362MB
Stop. WS64: 3844MB PMS64:15325MB
Wenn ich den Speicherverbrauch im Task-Manager sehe, wie dies in Process.WorkingSet64 ist. Was ist die wahre Zahl? Warum wird bei der Zuweisung Speicher zugewiesen? Ist ein Array tatsächlich ein kontinuierlicher Speicher? Ist ein Array ein Array? Existieren Aliens? (Dramatische Hintergrundmusik)
Folge 2: Wir machen eine kleine Änderung:
//lArray[i * JMAX + j] = i * JMAX + j;
var x= lArray[i * JMAX + j];
und nichts ändern (in der Ausgabe). Wo ist der Unterschied zwischen existent und nicht existent? (mehr dramatische Hintergrundmusik) Jetzt warten wir auf die Antwort eines der mysteriösen Menschen (Sie haben eine Nummer und ein kleines 'k' unter ihren Namen).
Folge 3: Eine weitere Änderung:
//lArray[IMAX * JMAX - 1] = 5000;
//l1Array[IMAX * JMAX - 1] = 5000;
//l2Array[IMAX * JMAX - 1] = 5000;
//l3Array[IMAX * JMAX - 1] = 5000;
//ShowTextWithMemAlloc("Last elements accessed.");
long newIMAX = IMAX-3;
long newJMAX = JMAX/10;
for (var i=0; i<newIMAX; i++)
{
for (var j=0; j<newJMAX; j++)
{
lArray[i * newJMAX + j] = i * newJMAX + j;
//var x= lArray[i * JMAX + j];
}
//ShowTextWithMemAlloc($"Value for row {i} assigned.");
}
ShowTextWithMemAlloc($"{newIMAX*newJMAX} values assigned.");
Der Ausgang:
Start. WS64: 14MB PMS64: 8MB
Arrays created. WS64: 15MB PMS64:15369MB
20000000 values assigned. WS64: 168MB PMS64:15369MB
Stop. WS64: 168MB PMS64:15369MB
PMS64 für eine Array (15.369-8)/4 = 3840MB Dies ist nicht sparse array, sondern teilweise gefülltes Array;). Ich benutze diese 168MB voll.
Antwort auf eine Frage "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 Speicher verloren. (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ängenden Speicher?
Antworten geben Antworten? Geheimnisvoll. (more music)
(Scully: Mulder, Kröten fiel vom Himmel Mulder:. Ich denke, ihre Fallschirme nicht geöffnet)
Vielen Dank!
* Ist ein Array tatsächlich ein fortlaufender zugeordneter Speicher? Ist ein Array ein Array? Existieren Aliens? * Ja. Ja. Wahrscheinlich, aber sie sind * weit weg *. –
Ich vermute, dass die (eigentlich interessante) Frage, die Sie vielleicht verpasst haben, "Ist Speicher tatsächlich Speicher"? ... und vielleicht "okay, aber wenn Speicher Speicher ist, ist zusammenhängende Speicher tatsächlich zusammenhängende Speicher?" - Nein, ich weiß wirklich nicht genug darüber, um eine Antwort zu schreiben. – moreON