Sto cercando un modo per tenere in memoria la grande struttura di array sparse 3d senza sprecare molta memoria. Qui ho fatto un esperimento con le matrici di Longs:Come una grande matrice alloca la memoria?
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.");
}
}
}
Se si desidera verificare che impostare la variabile d'ambiente COMPlus_gcAllowVeryLargeObjects (Progetto Proprietà -> Debug) per 1 o cambiare il jMax. E questo è l'output:
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
Quando vedo il consumo di memoria in Task Manager è come questo in Process.WorkingSet64. Qual è il numero reale? Perché la memoria è assegnata al compito? Una matrice è effettivamente una memoria allocata continua? Un array è un array? Esistono gli alieni? (Musica di sottofondo drammatico)
Episodio 2: Facciamo un piccolo cambiamento:
//lArray[i * JMAX + j] = i * JMAX + j;
var x= lArray[i * JMAX + j];
e niente cambio (in uscita). Dov'è la differenza tra esistente e inesistente? (musica di sottofondo più drammatica) Ora stiamo aspettando la risposta di una delle persone misteriose (hanno un numero e una piccola "k" sotto il loro nome).
episodio 3: Un'altra modifica:
//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.");
L'output:
Start. WS64: 14MB PMS64: 8MB
Arrays created. WS64: 15MB PMS64:15369MB
20000000 values assigned. WS64: 168MB PMS64:15369MB
Stop. WS64: 168MB PMS64:15369MB
PMS64 per un array (15.369-8)/4 = 3840MB Questo non array sparso, ma parzialmente riempito array;). Sto usando pieno questo 168 MB.
Risposta a qualche domanda "Perché non usi la misura esatta?". Perché io non lo so? I dati possono provenire da diversi SQL definiti dall'utente. "Perché non lo ridimensiona?". Ridimensiona crea un nuovo array e copia i valori. Questo è il momento di copiare, memoria e alla fine il malvagio GC arriva e ti mangia.
Ho perso memoria. (Non ricordo, gli alieni ?!) E quando si, quanto? 0, (3840-168) MB o (15369-8-168) MB?
Epilogo:
è un commento un commento o una risposta?
è memoria contigua effettivamente contigua alla memoria?
Le risposte danno risposte? Misterioso. (more music)
(Scully: Mulder, rospi appena sceso dal cielo Mulder:!. Credo che loro paracadute non si aprivano)
Grazie a tutti!
* Una matrice è effettivamente una memoria allocata continua? Un array è un array? Esistono alieni? * Sì. Sì. Probabilmente, ma sono * lontani *. –
Sospetto che la (davvero interessante) domanda che potresti aver perso sia "La memoria è effettivamente memoria"? ... e forse "okay, ma quando la memoria è memoria, la memoria è contigua alla memoria contigua?" - No, davvero non ne so abbastanza per scrivere una risposta. – moreON