Poszukuję sposobu na przechowywanie dużej, przestrzennej struktury tablic w pamięci bez marnowania dużej ilości pamięci. Tutaj zrobiłem eksperyment z tablic tęskni:W jaki sposób duża tablica przydziela pamięć?
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.");
}
}
}
Jeśli chcesz przetestować go ustawić zmienną środowiskową COMPlus_gcAllowVeryLargeObjects (Projekt Właściwości -> Debug) na 1 lub zmienić jMax. I to jest wyjście:
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
Kiedy widzę zużycie pamięci w Menedżerze zadań jest tak w Process.WorkingSet64. Jaka jest rzeczywista liczba? Dlaczego pamięć jest przydzielana do zadania? Czy tablica jest faktycznie ciągłą przydzieloną pamięcią? Czy tablica jest tablicą? Czy kosmici istnieją? (Dramatyczna muzyka w tle)
Odcinek 2: Wykonujemy małe zmiany:
//lArray[i * JMAX + j] = i * JMAX + j;
var x= lArray[i * JMAX + j];
i nic zmianę (na wyjściu). Gdzie jest różnica między istniejącym a nieistniejącym? (bardziej dramatyczna muzyka w tle) Teraz czekamy na odpowiedź od jednego z tajemniczych ludzi (mają oni pewną liczbę i małe "k" pod swoimi nazwiskami).
Część 3: Kolejna zmiana:
//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.");
Wydajność:
Start. WS64: 14MB PMS64: 8MB
Arrays created. WS64: 15MB PMS64:15369MB
20000000 values assigned. WS64: 168MB PMS64:15369MB
Stop. WS64: 168MB PMS64:15369MB
PMS64 do jednej tablicy (15369-8)/4 = 3840MB Nie jest to rzadki tablicy, a częściowo wypełniona tablica;). Używam pełnego tego 168 MB.
Odpowiedz na pytanie "Dlaczego nie używasz dokładnego rozmiaru?". Bo ja tego nie wiem? Dane mogą pochodzić z kilku SQL zdefiniowanych przez użytkownika. "Dlaczego nie zmieniasz rozmiaru?". Resize tworzy nową tablicę i kopiuje wartości. To jest czas na kopiowanie, pamięć i na końcu przychodzi zły zło i jedzą.
Czy marnowałem pamięć. (Nie pamiętam, kosmici ?!) A kiedy tak, ile? 0, (3840-168) MB lub (15369-8-168) MB?
Epilog:
jest komentarz komentarz lub odpowiedź?
jest ciągłą pamięcią sąsiadującą pamięć?
Czy odpowiedzi dają odpowiedzi? Tajemniczy. (more music)
(Scully: Mulder, ropuchy po prostu spadł z nieba Mulder!. Chyba ich spadochrony nie otwierają)
Dziękuję wszystkim!
* Czy tablica faktycznie jest ciągłą przydzieloną pamięcią? Czy tablica jest tablicą? Czy kosmici istnieją? * Tak. Tak. Prawdopodobnie, ale są * daleko *. –
Podejrzewam, że (faktycznie interesujące) pytanie, które mogłeś przegapić, brzmi: "Czy pamięć to pamięć"? ... i może "okej, ale kiedy pamięć jest pamięcią, sąsiadująca pamięć jest faktycznie ciągłą pamięcią?" - Nie, naprawdę nie wiem wystarczająco dużo na ten temat, aby napisać odpowiedź. – moreON