2015-06-30 5 views
6

Mam List<Matrix4>, gdzie Matrix4 jest strukturą zawierającą 16 elementów pływających, więc używa 16 * 4 bajtów = 64 bajty.C# List Wyjątek pamięci, ale daleki od ograniczenia 2Gb

Kiedy zaczynam dodawać elementy do listy, generuję wyjątek braku pamięci po przekroczeniu 1 miliona wierszy.

wiem, że .NET posiada limit 2 GB za przedmiot, ale chyba jestem całkowicie z mojego umysłu:

1.000.000 * 64 bajtów = ~ 61mb

który nie jest nawet blisko do limitu.

Po rozpoczęciu zapełniania listy, zgodnie z menedżerem zadań, moja aplikacja używa 896 MB, a do czasu, gdy osiągnę wyjątek, używa 1028 MB.

Komputer ma 8 GB pamięci fizycznej, ale korzysta tylko z 6 GB.

Jakieś wskazówki, dlaczego tak się dzieje?

--- UPDATE ----

Zmiana cel platformy na x64 rozwiązać ten problem na osobnym projekcie badawczym. Niestety oryginalny projekt nie może być x64 z powodu odniesień do bibliotek DLL x86, które nie działają na x64. Ale to kolejny problem.

Nie myślałem o zmianie na x64, ponieważ wydawało się, że jest daleko od limitów pamięci, ale sądzę, że Hans Passant był tuż przy 122mb, będąc zbyt blisko limitu 1,3 Gb. Dziękuję wam wszystkim.

+5

Nie jest to odpowiedź, ale nie można zliczyć takiej alokacji pamięci .NET. –

+1

należy użyć narzędzia w Visual Studio do profilowania wykorzystania pamięci. https://msdn.microsoft.com/en-us/library/dn342825.aspx –

+0

Nie sądzę, że to również odpowiedź. Ale każdy obiekt w .NET ma nagłówek z informacją. W aplikacji 32-bitowej nagłówek ma długość 8 bajtów, w aplikacji 64-bitowej nagłówek ma długość 16 bajtów. Tak więc, KAŻDY float zużywa 12 bitów długości (w aplikacji 32-bitowej). Bez widząc więcej kodu jest niemożliwe, o co chodzi. –

Odpowiedz

11

Duże struktury wykonuje się na stertach dużych obiektów (LOH) i podlegają one fragmentacji.

Podczas gdy prawdopodobnie masz wystarczającą ilość wolnej pamięci, możesz nie mieć 1 wystarczająco dużego bloku pamięci.

Twoje liczby (1M x 64) nie są wystarczające same przez się, tylko z wystarczającą ilością innych alokacji, które się na nie zajmą, wyjaśniają problem. Możesz spróbować rozwiązać ten konkretny problem, ale prawdopodobnie jest to kwestia, w której pojawia się większy problem.

Zasadniczo TaskManager nie jest właściwym narzędziem do diagnozowania problemów z pamięcią. Potrzebujesz profilera pamięci, aby dowiedzieć się, co się dzieje.

Zależy to również od wersji twojej platformy i od tego, czy jest to 32, czy 64 bity.

+0

Jaka byłaby tutaj duża struktura? Czy "Matrix4" nie jest zbyt mały, aby być w LOH? –

+1

@Asad - Tak, ale są to typy wartości, więc lista <> będzie zawierała tablicę bajtów Nx64. Z dużym numerem –

+0

Ah, tak że nawet pojedyncze duże obiekty mogą być przydzielane w porcjach przez LOH (a więc powodować problemy z fragmentacją)? –