niedziela, 29 kwietnia 2012

WebBrowser i cieknąca pamięć

Jeśli kiedykolwiek używaliście domyślnego WebBrowsera w C# to za pewne zauważyliście, że ilość pamięci zużywanej przez wasz program rośnie wraz z użytkowaniem tej kontrolki w zasadzie w nieskończoność. Dlaczego tak się dzieje? Cóż dokładnie nie wiadomo, wiadomo jednak, że jest to spowodowane głównie cachowaniem zawartości odwiedzonych stron... dodajmy cachowaniem, którego nie można w całości wyłączyć/wyczyścić. Oczywiście można by sądzić, iż problem ten wynika z leciwości tej kontrolki, jednak ku memu wielkiemu zaskoczeniu to samo dzieje się z WebBrowserem dostępnym wewnątrz WPF (obie kontrolki używają tego samego silnika IE).
Ale po co w ogóle używać kontrolkę WebBrowser? Poza oczywistym zastosowaniem - umożliwienia "przeglądania" Internetu (klikania w łącza, oglądania obrazków, czytania tekstów) można również używać go do parsowania ściągniętych plików HTML, z którymi natywne parsery .NET nie dają sobie rady z racji niezgodnego ze standardem użycia tagów.

Oczywiście to do czego chcemy używać WebBrowser jest sprawą drugorzędną, gdyż wpływa jedynie na to czy istnieje jakieś rozwiązanie alternatywne, czy też skazani jesteśmy na WebBrowsera, który pożre przy sprzyjających dla siebie warunkach wszelkie ilości dostępnej pamięci nie dając w zamian absolutnie nic. W tym wpisie przedstawię kilka sposobów na ograniczenie ilości wyciekającej pamięci, więc jeśli ktoś liczy na to, że znajdzie tu sposób na całkowite zażegnanie tego problemu to spotka go rozczarowanie, gdyż takie sposobu nie znam, ani nigdzie nie mogłem znaleźć... Obalę również kilka mitów krążących po sieci związanych z "magicznymi sposobami" na ograniczenie używanej pamięci. Oczywiście zawsze można zaprzestać używania natywnych kontrolek i wykorzystać kontrolki stworzone w pocie czoła innych programistów (dla porównania w dalszej części przedstawię właśnie kontrolkę Awesomium):