2012-10-23 13 views
8
var a = new double[7000,7000]; 

FillValue(a,3); 

Wygląda na to, że .NET nie przypisuje żadnej pamięci do a po wykonaniu pierwszego wiersza. Tylko podczas wykonywania połączenia FillValue zjada pamięć. (czyli około 400 MB)dlaczego .net nie przydziela pamięci po zainicjowaniu tablicy 2d?

Czy ktoś może podać mi więcej informacji na ten temat? Myślałem, że a jest wypełnione 0 po domyślnej inicjalizacji, w jaki sposób może nie mieć żadnej pamięci w ogóle?

+4

W jaki sposób mierzysz, czy przydziela pamięć? –

+0

@SethCarnegie Niestety, użyłem bardzo prymitywnego sposobu ... po prostu spójrz na menedżera zadań Windows .. i ustaw punkt przerwania, uruchom kilka razy w pętli. Jest to pamięć 400 MB na "wypełnienie", które jest łatwe do wykrycia. – colinfang

+1

Może to być również spowodowane systemem operacyjnym. Zobacz "Kombinacja pamięci" http://blogs.msdn.com/b/b8/archive/2011/10/07/reducing-runtime-memory-in-windows-8.aspx –

Odpowiedz

9

Istnieją dwa sposoby "przydzielania pamięci" w systemie Windows: do "rezerwacji" i "zatwierdzania" pamięci.

Menedżer zadań wyświetla tylko "Historię użycia pamięci fizycznej"; maszyna wirtualna .NET najwyraźniej używa tylko zarezerwowanej pamięci, kiedy przydzielasz tablicę, a następnie wraca i zatwierdza używane części.

W ten sposób można zarezerwować pamięć bez pobierania jej, co jest bardziej wydajne, i rezerwowania pamięci, zgodnie z MSDN, "rezerwuje zakres wirtualnej przestrzeni adresowej procesu bez przydzielania rzeczywistej fizycznej pamięci w pamięci lub w pamięci plik stronicowania na dysku ". Dlatego Menedżer zadań tego nie pokazuje.

Możesz przeczytać więcej na ten temat na stronie VirtualAlloc na stronie MSDN.

Jest to jednak szczegół implementacji, więc nie powinieneś polegać na nim ani nic. Na przykład maszyna wirtualna Mono prawdopodobnie zachowuje się inaczej.

+1

Zastanawiam się, czy możemy skorzystać z niego podczas pracy nad rzadkimi manipulacjami matrycowymi. – colinfang

7

Właściwie to przydziela pamięć jak widać tutaj:

http://ideone.com/Cd4BR1

Console.WriteLine("Memory before: {0}",GC.GetTotalMemory(true)); 
var a = new double[5000,5000]; 
Console.WriteLine("Memory after: {0}",GC.GetTotalMemory(true)); 

Memory before: 118784 
Memory after: 200224768 

(konieczna, aby zmniejszyć rozmiar tablicy, aby zapobiec OutOfMemoryException na ideone)

GC.GetTotalMemory Method

Pobiera liczbę bajtów, które obecnie są przydzielane.

+1

FWIW ideone używa Mono. –

+3

świetny przykład, thx, nauczyłem się nowej metody dzisiaj :) – colinfang

Powiązane problemy