2008-11-19 6 views
22

Pochodzące z tła java, jedną z rzeczy, do których jestem przyzwyczajony, jest przekazywanie JVM informacji o maksymalnym rozmiarze sterty. Jeśli uruchomiony program próbuje połknąć więcej, niż jest to dozwolone, a garbage collector nie może zwolnić więcej zasobów, wtedy OutOfMemoryError jest generowany i wszystko idzie hukiem. Dlatego ustawienie maksymalnej wielkości sterty jest ważne w Javie.Czy mogę (i czy kiedykolwiek chcę) ustawić maksymalny rozmiar sterty w .net?

Czy dotyczy to sieci .net? Czy można ustawić ograniczenia wielkości sterty? Czy CLR ciągle rośnie, dopóki nie osiągnie fizycznych ograniczeń maszyny? Czy nie jest to problem w .net z jakiegoś subtelnego powodu, że moje migacze Java nie pozwalają mi zobaczyć?

Odpowiedz

19

Nie można ustawić maksymalnego rozmiaru sterty w .Net, chyba że hostujesz CLR w procesie.

Edit: Aby kontrolować alokacji pamięci z CLR w tym rozmiarze maks sterty, trzeba użyć API hosting gospodarzem CLR a konkretnie użyć „interfejsy menedżer pamięci”, niektóre rozrusznik informacji można znaleźć tutaj MSDN Magazine, column CLR Inside Out : CLR Hosting APIs

Edytuj: aby odpowiedzieć na pytanie, dlaczego chcesz kontrolować przydzielanie pamięci lub konkretnie maksymalny rozmiar sterty, zwykle nie chcesz, ale jeśli piszesz aplikację podobną do SQL Server lub IIS albo aplikacja w czasie rzeczywistym, to masz całkiem dobry powód, by mieć kontrolę nad pamięcią, a konkretnie, unikaj stronicowania, inaczej CLR i system operacyjny wykonają już dla ciebie całkiem niezłą robotę, a co pozostało jest zapewnienie, że aplikacja używa minimalnych zasobów, aby wszystko działało dobrze.

+0

Dzięki - ciekawe informacje na temat hostingu CLR. Prawdopodobnie przesada dla tego, kim teraz jestem Diong - po prostu upewnię się, że nie jestem świnią pamięci. – serg10

+1

Współdzielone środowiska serwerów, które obsługują wiele aplikacji, powinny zapewnić, że maksymalna pamięć przydzielona przez wszystkie aplikacje klienckie nie spowoduje przecięcia dostępnej pamięci. Nie chcesz, aby jedna niewłaściwie działająca aplikacja usuwała cały serwer, ponieważ alokuje całą dostępną pamięć. –

+2

@Kelly, to jest to, co robią usługi IIS i SQL Server, ponieważ są hostami dla innych zarządzanych aplikacji i kontrolują ile pamięci mogą mieć hostowane aplikacje ... z drugiej strony niehostowana aplikacja .Net jest bezpłatna alokować tyle, ile ma aplikacja natywna, nie ma tam żadnej różnicy (dlatego w .net host apis musi być używany do kontrolowania ilości przydzielonej pamięci) –

12

Nie, nie ma zastosowania w .NET. Kupa rzeczywiście rośnie, dopóki nie będzie mogła już rosnąć. (Oczywiście jest to "po próbie odzyskania pamięci przez GC, wzrost sterty".) Zasadniczo nie ma prawie tak dużo dostrojenia dostępne w .NET GC, jak w Javie. Możesz wybrać serwer GC lub klienta, i myślę, że istnieje opcja włączania/wyłączania współbieżnego GC (znajdę linki za minutę), ale to w zasadzie to.

EDYCJA: Wygląda na to, że jest w nim trochę więcej, choć niezbyt duża. Rick Minerich's blog entry on GC settings i the subsequent one wydaje się wiedzieć więcej niż ja w tej sprawie. Są one prawdopodobnie dobrym punktem wyjścia do dalszych badań - ale w większości są to flagi, a nie ograniczenia pamięci dostępne w maszynach JVM.

EDYCJA: Odpowiedź Pop'a porusza dobry punkt - zakładam "normalny" model hostingu CLR (tzn. Nie jest pod Twoją kontrolą). Jeśli chcesz podejść do samodzielnego hostowania, możesz uzyskać znacznie większą kontrolę - kosztem dodatkowej pracy hostingu. Nie mogę powiedzieć, że kiedykolwiek zaglądałem w tę stronę rzeczy.

4

O ile znalazłem, nie ma prostego sposobu na control the size of the heap aplikacji .Net przy użyciu CLR.

Łącze powyżej tylko połowa odpowiada na pytanie. Kiedy zbadałem ten sam problem, odpowiedź brzmi: "Sterty rosną, aby wykorzystać całą dostępną pamięć", jakby to był jedyny powód, dla którego chcesz kontrolować maksymalny rozmiar sterty.

Na środowiskach (zazwyczaj Java) serwerów, nie chcesz, aby źle zachowująca się aplikacja hogowała pamięć kosztem innych hostowanych aplikacji. Prostym rozwiązaniem jest ograniczenie ilości pamięci, z której aplikacja może korzystać w swoim sterty. Jest to możliwe dzięki argumentowi Java -Xmx, dzięki czemu możesz zagwarantować, że aplikacja nie użyje więcej niż to, co jest planowane, np. -Xmx256M.Ponieważ przydzielanie pamięci na stercie podczas inicjalizacji może spowolnić uruchamianie aplikacji, Java używa argumentu -Xms, aby zezwalać aplikacjom, które wykonują wiele zadań podczas inicjowania, aby rozpocząć z dużym blokiem sterty zamiast JVM, niezależnie od rozmiaru sterty, ponieważ idzie.

. CLR środowiska .Net nie ma tej zdolności. Podejrzewam, że tak jest, ponieważ CLR .Net nie jest maszyną wirtualną. CLR okazuje się być API (dość obszernym, mogę dodać), który służy jako adapter do rodzimych .dlls, które są podobne do podejścia bardziej przypominającego plik wykonywalny, jeśli chodzi o zarządzanie pamięcią.

Zadałem to pytanie dotyczące rozwoju SharePoint i usłyszałem, że można kontrolować heapsize za pomocą modułów IIS zwanych Web Apps, dzięki czemu można powiedzieć IIS, aby ograniczyć pamięć danej aplikacji internetowej. Zastanawiam się, czy to dlatego, że IIS ma niestandardowe procedury, które zastępują/zastępują new()/malloc()/etc, a tym samym mogą zapewnić ten typ kontroli aplikacjom klienckim. Oznacza to, że samodzielne aplikacje .Net nie mają szczęścia, chyba że chcesz napisać niestandardowego menedżera pamięci w C++ i utworzyć interfejs dla .Net