2013-02-27 11 views
6

Mam zestaw AsyncController skonfigurowany do wykonywania akcji z długim odpytywaniem. Wszystko działa dobrze, jednak kolega zauważył wyciek pamięci na serwerze, który wydaje się zwiększać z każdym nowym połączeniem.Przeciek pamięci MVC 4 IIS dla każdego połączenia

Stworzyłem niewielką aplikację do żądania z tej strony tysiące razy i monitoruję wykorzystanie pamięci dla procesu IIS. Każde połączenie zwiększa wykorzystanie pamięci, ale nie spada z powrotem, gdy klient się rozłączył.

Po dalszych badaniach, stwierdziliśmy, że to nadal zdarza się nawet, kiedy zastąpić mój AsyncController ze standardowym Controller że nie robi nic poza tym:

public class WaitController : Controller 
{ 
    public JsonResult Member(string oauth_token, int service_id, bool busy = false) 
    { 
     return Json(new 
     { 
      ready = false, 
     }, JsonRequestBehavior.AllowGet); 
    } 
} 

Chociaż w tym, nie ma tyle zużycie pamięci zachowanie wydaje się być dokładnie takie samo.

Uruchomiłem program do profilowania pamięci, aby pokazać różnicę między 10.000 połączeń i tam prawie nic nie ma. Najwięcej pamięci zajmują instancje ExpiresEntry[] z System.Web.Caching lub System.Runtime.Caching, jednak są one całkowicie zerowe w porównaniu ze wzrostem pamięci, który uzyskuję w procesie roboczym IIS.

Moje pytanie brzmi:, czy IIS robi to zgodnie z projektem? Być może zostało to przydzielone do wątków łączących, które kręcą się na wypadek, gdyby były potrzebne później? Czy jest to błąd z IIS, ASP.NET lub MVC 4?

To była moja decyzja, aby korzystać z funkcji WebAPI MVC 4 za to, bo chcemy, aby być elastyczne, utrzymaniu, przyszłościowe i być dostępne za pośrednictwem AJAX. Wydaje się również, że ma to sens z punktu widzenia rozwoju, ponieważ zbudowaliśmy także stronę internetową w MVC 4.

Jednak kolega teraz podniesiony to jako krytyczny problem z architekturą systemu, jak będziemy (w przyszłości) potrzebują tysiące klientów podłączonych. Sugeruje, że zamiast tego użyjemy WCF. Pytanie dodatkowe - czy za pomocą WCF uda się rozwiązać te problemy?

+0

Czy jesteś pewien, że pamięć wycieka? Czy to możliwe, że po prostu trzymasz się go, ponieważ nie ma wystarczającej siły, by go porzucić? Czy zweryfikowałeś, że jeśli będziesz kontynuował test połączenia, że ​​na serwerze skończy się pamięć? – Pete

+0

@Później zaczyna zwalniać. Nigdy nie widziałem, żeby zabrakło w nim pamięci, ale cała pula aplikacji stopniowo zwalnia do punktu, w którym nie nadaje się do użytku. Rozwiązuje to ponowne uruchomienie puli aplikacji. Czy IIS potrzebuje "nacisku", aby zrezygnować z przydzielonej pamięci? Zła wydajność, jak sądzę, może oznaczać, że każde połączenie czeka w kolejce, aby mogło zostać przetworzone. – Connell

Odpowiedz

2

Jest świetny article od inżyniera polowego MS na ten temat. Może pomóc.

+0

Czy to powiedzenie, że oczekuje się zachowania? '" Nie można uniknąć fragmentacji pamięci i innej naturalnej degradacji, a recykling zapewnia okresowe czyszczenie aplikacji "'. Czy firma Microsoft zachęca nas do rozwiązania tego problemu, automatycznie przetwarzając pulę aplikacji? – Connell

+0

Tak zwykle robię. :) – rusev

0

Po dalszych eksperymentach i testach odkryłem, że niestety nie można temu zapobiec. Wygląda na to, że jest albo z projektu, albo z głęboko zakorzenionego problemu z usługami IIS.

zmieniłem sposób korzystania z opcji niższego poziomu: Wdrożenie IHttpAsyncHandler zrobić to samo. Użyłem numeru custom HttpHandler route for MVC, aby umożliwić mi używanie dokładnie tych samych adresów URL, z których korzystałem wcześniej. Problem nadal istniał, ale w nieco mniejszej skali.

Następnie próbowałem całkowicie pustego IHttpHandler, który po prostu zwraca { ready: false } (jak mój kod zrobiłby na timeout). Żaden inny kod nie jest włączony do HttpHandler, ale ten sam problem nadal występuje.

Następnie wypróbowałem całkowicie pustą usługę WCF, która również zwróciła { ready: false }. Ten sam problem, ale tym razem na jeszcze mniejszą skalę.

jako link @rusev „s odpowiedź sugeruje: rozdrobnienie

pamięci i innych degradacja fizyczna nie da się uniknąć i recyklingu zapewnia, że ​​aplikacje są okresowo czyszczone.

Może to być przyczyną problemu. Mogę sobie wyobrazić, że ponieważ przy użyciu kontrolera MVC jest więcej narzutów, fragmentacja dzieje się szybciej. Korzystanie z metod niższego poziomu, takich jak HttpHandler lub usługa WCF, zużywa mniej pamięci na połączenie, dlatego powoduje mniej fragmentacji.

Powiązane problemy