Spoglądacie czasem na aktywne w systemie procesy? Mi się zdarza. Wprawdzie nie tylko dzięki takiemu spoglądaniu wiem, że każda zakładka w IE8 to oddzielny proces, ale gdyby ktoś jeszcze nie wiedział – łatwo to sam zauważy. Ostatnio jednak, przyjrzałem się procesom dokładniej i zauważyłem jeszcze jedną rzecz:

IE_process

Podany w poleceniu parametr to PID (zwany w WinDBG dla niepoznaki Cid) jednego z procesów Internet Explorera.

W wyniku wyraźnie widać pole Job. Nie wiem jak po polsku fachowo nazywa się obiekty tego typu. Mogę łatwo znaleźć polski odpowiednik, jednak pozostanę przy "obiekt Job" bo dzięki temu uniknę niejasności. Job jest specyficznym obiektem grupującym procesy po to, żeby sprawnie nimi zarządzać traktując je w pewnych aspektach jak jedną całość. Opisany jest w MSDN, więc zainteresowanych odsyłam. W każdym razie uważam, że właśnie takiego grupowania trzeba przeglądarce! Niby to oddzielne procesy (pozostawię na inną okazję polemikę czy to dobrze czy źle) ale w sumie też jakby jedna całość z punktu widzenia użytkownika. Stąd idea wspólnego zarządzania bardzo mi się podoba.

Poniważ Job jest grupą procesów, możemy łatwo odczytać pewne parametry dla całej grupy. Wymienić tu można między innymi:

  • Sumaryczny czas procesora (zliczany oddzielnie dla trybu kernel i user)
  • Łączna ilość błędów stron
  • Ilość procesów (oddzielnie dla aktywnych i w ogóle kiedykolwiek istniejących)
  • Ilość bajtów przesłanych do i z podsystemu I/O

Odczytanie takich danych nie jest specjalnym wyzwaniem nawet, gdybyśmy nie mieli obiektu Job. Wystarczyłoby zsumować takie informacje dla wszystkich procesów, które nas interesują i wynik wyszedłby taki sam. Powiedzmy, że jakiś problem mielibyśmy tylko przy procesach, które uległy zakończeniu. Job o nich "pamięta" a inne mechanizmy niekoniecznie. Od odczytywania historii ciekawsze jest jednak nakładanie na obiekt Job ograniczeń. Można to zrobić! Oznacza to, że mając Job, możemy powiedzieć, że należące do niego procesy mogą robić co chcą, na przykład pod warunkiem, że nie będzie ich więcej niż 10. Albo że łącznie nie zużyją więcej niż 15s czasu procesora. Ograniczeń jest wiele i do powyższych przykładów dodać można chociażby:

  • Ograniczenie procesorów, na których mają się wykonywać istniejące i nowe procesy należące do tego samej grupy (obiektu Job)
  • Łączna ilość pamięci dla wszystkich procesów w grupie
  • Minimalny i maksymalny rozmiar WorkingSet dla procesów (de facto oznacza to ilość faktycznie zajętej pamięci RAM)
  • Zakazy dotyczące jednej z ośmiu możliwych akcji (JOBOBJECT_BASIC_UI_RESTRICTIONS) w systemie. Biorąc pod uwagę, że obiekt Job, o którym tu mówimy dotyczy przeglądarki, dojdziemy do wniosku, że może to nie być takie głupie.

Warto więc w przypadku IE8 spojrzeć głębiej na właściwości obiektu Job:

IE_job

Niestety wydaje się, że domyślnie żadne ograniczenia nie są narzucone. Może to źle a może dobrze... Ważne, że procesy są połączone w grupę, więc można nią zarządzać, jeżeli tylko zajdzie taka potrzeba. Teoretycznie to proste. Wystarczy odwołać się do obiektu Job przy pomocy OpenJobObject. Proste, bo wystarczy podać nazwę obiektu (uwaga bo duże / małe litery ma znaczenie). Nazwę obiektu...? Weźmy na przykład obiekt Job dla procesu wmiprvse.exe. W tym przypadku, w obiekcie Job wyraźnie widać nałożone ograniczenia.

wmiprvse_job

Jego nazwa to \BaseNamedObjects\WmiProviderSubSystemHostJob. Ale dla IE8 nazwy takiej nie ma! Jest to jak najbardziej dozwolone, ale w praktyce oznacza jedno: do takiego obiektu nie można się oficjalnymi kanałami dostać z zewnątrz. Oficjalnymi. Kernel debugger trudno uznać za oficjalny kanał, ale zawsze możemy spróbować:

ie_limited

Wychodzi na to, że udało nam się ograniczyć grupę procesów IE do 2 sztuk, choć to nieco złożona metoda, zwłaszcza dla użytkownika bez praw administratora.

Warto jeszcze spojrzeć na tak zwane "konkurencyjne przeglądarki". W firefoxie jest prosto. Skoro twórcy tak długo nie pojęli, czym są integrity levels, to trudno się dziwić, że wszystkie zakładki pracują w jednym procesie jak w wersji 1.0. Należy jednak przyznać, że jest to konsekwentna polityka. Niezależnie od ilości okien, proces nadal pozostaje tylko jeden.

Ciekawiej jest w Chrome. Tu każda zakładka jest oddzielnym procesem. Sprawdzenie takich procesów daje bardzo interesujące rezultaty. Wprawdzie prawie każdy (wcale nie wszystkie!) proces należy do grupy, ale każdy do oddzielnej! O co chodzi – nie wiem. Obiekty Job podobnie jak w IE8 nie mają nazwy, mają jednak domyślnie narzucone ograniczenia dozwolonych działań.

chrome_job

Skupiając się jednak na IE8, warto stwierdzić, że o ile podejście jedna zakładka = jeden proces może budzić kontrowersje, o tyle połączenie tych procesów w jedną grupę (obiekt Job) jest pomysłem zdecydowanie dobrym. Co więcej, w jedną grupę łączone są nie tylko zakładki jednego okna, ale wszystkie procesy związane z IE8, niezależnie od tego ile okien zajmują. Wprawdzie w chwili obecnej (wersja 8.0.6001.18702) trudno się do takiego obiektu z zewnątrz "dobrać", ale wydaje się, że funkcjonalności będące efektem zastosowanego podejścia dostępne są na wyciągnięcie ręki.

Autor: Grzegorz Tworek [MVP]

PS. Gdyby ktoś znał metodę uzyskania uchwytu do Job Object bez nazwy – będę wdzięczny za podpowiedź. Programista ze mnie żaden a wyszukiwarki jakoś niewiele pomogły.