Mieliśmy skrypt konwersji obrazu działający na .NET 4.0, IIS 7, ASP.NET, 4 GB pamięci RAM serwera, który zmienia rozmiar dużych obrazów i dlatego potrzebuje dużo pamięci.

Pierwszy skrypt zwiększył zużycie pamięci do prawie 100%, nie pozostawiając praktycznie nic dla uruchomionego serwera SQL Server (który zrezygnował z pamięci do czasu uruchomienia na 20 MB zamiast zwykłych 900 MB).

W drugim skrypcie dodaliśmy GC.Collect() i (dla pewności) jednosekundowy wątek uśpiony po każdym cyklu i wszystko wróciło do normy.

Pytanie: czy nie jest to wada w zarządzaniu pamięcią .NET? Czy system nie powinien przyjrzeć się bliżej temu, co dzieje się z dostępną pamięcią, spowolnić działania i posprzątać?

3
Olaf 15 czerwiec 2011, 11:54
Dlaczego na serwerze uruchamiasz coś innego niż serwer SQL?
 – 
Mitch Wheat
15 czerwiec 2011, 11:59
Podobnie jak „SELECT nie jest uszkodzony” Zbieranie śmieci .NET nie jest zepsute....
 – 
Mitch Wheat
15 czerwiec 2011, 12:00
Założę się, że śmieciarz .net wykonuje swoją pracę prawidłowo i masz zarządzany wyciek
 – 
Stormenet
15 czerwiec 2011, 12:05
Jeśli skonfigurujesz SQL Server tak, aby miał, powiedzmy, co najmniej 500 lub 900 MB pamięci, co się wtedy stanie?
 – 
Damien_The_Unbeliever
15 czerwiec 2011, 12:22
Pszenica: jest to wynajęty dedykowany serwer sieciowy, na którym działają IIS i SQL Server (i kilka innych rzeczy). Myślę, że standardowa konfiguracja (oczywiście byłoby lepiej mieć dwa serwery, ale w tym przypadku nie ma potrzeby wydajności w codziennej pracy). Po drugie, nigdy nie powiedziałem, że GC "jest zepsuty", ale w świecie IT SĄ błędy, od czasu do czasu...
 – 
Olaf
15 czerwiec 2011, 14:05

3 odpowiedzi

Najlepsza odpowiedź

Zgodnie z dokumentacją:

Wyrzucanie elementów bezużytecznych odbywa się automatycznie, gdy żądanie pamięci nie może zostać spełnione przy użyciu dostępnej wolnej pamięci.

Zakładam, że ta sytuacja nie została spełniona, ponieważ zamiast tego SQL Server wycofuje się. Jeśli chodzi o bycie błędem; doktorzy sugerują, że jest to zgodne z projektem.

4
m.edmondson 15 czerwiec 2011, 12:02
To prawda, ale czy nie jest również prawdą, że „odśmiecanie odbywa się automatycznie” tylko wtedy, gdy jest na to czas? Co jeśli serwer jest zbyt zajęty?
 – 
Olaf
15 czerwiec 2011, 14:14

Tak garbage collection wykonuje swoje zadanie, gdy pamięć nie wystarcza do następnej operacji. Ale.

GC nie ma wpływu na obiekty, które są zadeklarowane jako globalne lub używane przez obiekty globalne. Więc staraj się, aby twoje obiekty były lokalne, jeśli to możliwe.

1
Arun 16 sierpień 2012, 08:48

Może to być usterka w zarządzaniu pamięcią .Net. Aby mieć pewność, potrzebujemy Twojego kodu.

Ale najpierw przyjrzę się Twojemu kodowi pod kątem przypadków, w których jednorazowe zasoby nie są prawidłowo usuwane. Wiadomo, że powoduje to wycieki pamięci i jest przyczyną istnienia interfejsu IDisposable.

0
Falanwe 15 czerwiec 2011, 12:02
Usunęliśmy użyte obiekty — Image i Bitmap zostały zainicjowane przy użyciu nawiasów. Mimo to, ponieważ GC.Collect() działa poprawnie, czy to nie dowodzi, że obiekty zostały usunięte prawidłowo?
 – 
Olaf
15 czerwiec 2011, 14:12