2014-04-22 27 views
8

Mamy 32-bitową usługę Windows, która wycieka z pamięci - generowany jest wyjątek OutOfMemory. Jest to plik wykonywalny .net 4.0 uruchomiony na Windows Server 2003. Podczas debugowania plików zrzutu awaryjnego za pomocą WinDbg, widzę, że większość pamięci jest w rzeczywistości zarezerwowana i nie jest zatwierdzona. enter image description hereCzy pamięć zarezerwowana może spowodować wyjątek braku pamięci

Jak widać z WinDBG zrzucie istnieje 2,5 Gb niesklasyfikowanych zużycie pamięci, a większość z nich jest faktycznie 2,1 Gb zastrzeżone pamięci (MEM_RESERVE). Mam doświadczenie w debugowaniu zgniłych reklam, ale ten scenariusz jest dla mnie czymś nowym. MEM_COMMIT jest rzucić OK - 564,270 Mb udało wielkość sterty jest ABT 82 Mb

enter image description here

Ja również sprawdzone rodzimych stosy, aby zobaczyć, czy są duże ilości danych zakonserwowane, ale nie mógł znaleźć niczego podejrzanego nie bądź

enter image description here

Więc moje pytanie jest - czy to możliwe, że MEM_RESERVED może spowodować wyjątek OOM? Jeśli tak, jak mogę go debugować, zobacz dlaczego/jak ogromna ilość pamięci jest rezerwowana? Gdzie indziej szukać, co może być problemem?

Jeśli wymagane są inne informacje, poproś o to, a zaktualizuję mój wpis.

Odpowiedz

6

Tak, rezerwacja pamięci może uruchomić OutOfMemoryException. Spróbuj przydzielić kilka bardzo dużych tablic bajtowych. Pamięć dla nich nie zostanie zatwierdzona, dopóki nie napiszesz do zawartości tablic. Możesz jednak łatwo wyzwolić OOM przez przydzielenie tych tablic.

Nie znam szczegółów implementacji, ale ponieważ VirtualAlloc zawiedzie, jeśli nie może spełnić żądania rezerwy, zakładam, że CLR tłumaczy to na wyjątek. Nie rozumiem, w jaki sposób można przekształcić żądanie braku rezerwy w coś użytecznego, więc wyjątek stanowi rozsądny wybór.

+0

dziękuję za odpowiedź, czy wiesz przez przypadek, jak mogę zobaczyć, co rezerwuje tę ogromną pamięć w WinDbg? – Michael

+0

Zakładając, że pamięć jest używana przez zarządzany obiekt, możesz je sprawdzić za pomocą '! Dumpheap' i'! Do'. Jednakże, biorąc pod uwagę, że wyjście '! Eeheap' pokazuje, że zarządzana sterty jest mała, zakładam, że coś innego zarezerwowało tę pamięć. –

+0

Czy możesz określić, co jeszcze może zarezerwować pamięć? Jestem zdezorientowany, ponieważ oczekiwałbym, że "coś" jest albo na sterowanej kupie, albo jakimś rodzimym zasobem na rodzimych hałdach - żadne z nich nie wskazuje na coś podejrzanego. Co jeszcze może zarezerwować pamięć? Z przyjemnością sprawdzę to od razu. – Michael

3

OutOfMemoryException występuje, jeśli system nie może przydzielić więcej pamięci wirtualnej dla aplikacji. Pamięć zarezerwowana jest pamięcią wirtualną i dlatego obsługuje ten limit.

Można spróbować, że w C++ najbardziej prosty sposób:

while(::VirtualAlloc(NULL, 65536, MEM_RESERVE, PAGE_READWRITE) != NULL); 
std::cout << "All memory reserved. Now check with tools." << std::endl; 

Jeśli VirtualAlloc() zwraca NULL, to nie może przeznaczyć więcej memoy. W WinDbg będzie to pokazać

MEM_RESERVE 32307 7f6f2000 (1.991 Gb) 99.59% 99.56% 

Jednak VirtualAlloc() nie przydzielić pamięci na stercie, więc !heap nie jest przydatna w tym przypadku i pokazuje tylko kupa domyślny proces:

0:000> !heap 
Index Address Name  Debugging options enabled 
    1: 00440000 

To w inny sposób: heap mamanger używa VirtualAlloc(), aby uzyskać pamięć. Zauważ też, że .NET również nie używa menedżera sterty. Przydziela również pamięć bezpośrednio za pomocą VirtualAlloc(), a następnie zarządza nią samodzielnie. Tak więc, ponieważ można go zobaczyć na wyjściu z !heap, nie jest to problem .NET, jest to problem z natywną pamięcią.

W moim naiwnym zrozumieniu ustawienie gflags powinno być pomocne przy ustalaniu źródła przydziału sterty. Jednak moje oczekiwanie, że polecenie !heap -t po prostu wyświetli nazwę biblioteki DLL, która alokowała pamięć, nie spełniło się.

+0

dziękuję za wejście. Próbowałem polecenia! Heap -t, ale nic nie dało pożytku. Próbuję zagłębić się w rodzimą pamięć, żeby zobaczyć, co mogę tam znaleźć. Wszelkie inne sugestie dotyczące sprawdzenia czegoś innego są bardzo mile widziane. – Michael