7

Mam aplikację, która wywołuje pracownika WWW po kliknięciu przycisku. Obliczenia są przenoszone do procesu roboczego w celu zwolnienia interfejsu użytkownika i dostosowania go do działań użytkownika podczas wykonywania obliczeń.Możliwe wycieki pamięci za pomocą pracowników WWW (Garbage Collector)

Wszystko idzie dobrze i po około 0,8-1,5 s pracownik wysyła odpowiedź. W pliku worker.onmessage wykonuję wszystkie wymagane działania DOM. Ale po tym pojawia się GC i praktycznie blokuje interfejs użytkownika na 2 lub więcej sekund w zależności od procesora. To jest naprawdę mylące, ponieważ blokowanie interfejsu użytkownika jest tym, co chcę zapobiec.

Oto zrzut ekranu z zakładki konsoli timeline/pamięci: http://i.imgur.com/zUoHa.jpg

Jak widać imprezy GC zdarzyć zaraz po wszystkich manipulacji DOM. Właściwie istnieje tylko jedno przemalowanie (używane jest narzędzie DocumentFragment). Kod

główne js:

var sortWorker = new Worker('js/contactsorter.js'); 
sortWorker.onmessage = function(e) { 
    var messages = []; 
    e.data.forEach(function(userDoc) { 
     var contactSection = _drawContact(userDoc); 
     messages.push(contactSection); 
    }); 

    meta.append(messages); // this actually appends document fragment as a child 
}; 

sortWorker.postMessage(postMessageData); 

contactsorter.js (robotnik):

onmessage = function(e) { 
    var uid, output = [], usersStat = {}; 

    // calculations... 

    postMessage(output); 
    close(); 
}; 

Czy istnieje jakiś sposób, aby uniknąć tych wydarzeń GC w tym miejscu, czy nie?

UPD: Wydaje mi się, że czas zdarzeń GC zależy od ilości danych wysłanych do pracownika. UPD2: Po wyłączeniu i rozruchu zdarzenia GC zdarzają się tylko dwukrotnie, blokując w ten sposób interfejs użytkownika przez mniej niż sekundę. Hm?

+0

Jak duże są obiekty? Ile? Jakimi liczbami rozmawiamy? Jakie węzły DOM tworzysz? Czy zdarzenie GC jest skalowane liniowo z liczbą sortowanych kontaktów? –

+0

JSON.stringify mówi, że chodzi o 2M. Są to obiekty, które mają obiekty jako ich dzieci. Po odpowiedziach pracowników (wyprowadza tablicę) tworzę DocumentFragment i dołączam ok. 400 elementów "div" do niego. Następnie dołączam fragment do DOM. Odnośnie ostatniego pytania - muszę przepisać mój kod, aby wykonać test, więc opiszę to nieco później.Btw: nowy UPD –

+0

Odnośnie ostatniego pytania: nie, zdarzenie GC nie jest skalowane zgodnie z ilością danych. Co więcej, nie mogę nawet znaleźć go na osi czasu http://i.imgur.com/psGpr.png chociaż w tym okresie jest aktualizowany interfejs użytkownika. –

Odpowiedz

3

Jedną rzeczą do zapamiętania dla pracowników sieci Web, a zwłaszcza dla ich użycia w przykładzie, jest klonowanie obiektu podczas wysyłania go do pracownika. Więc pozwala uruchomić poprzez to z głupim przykład:

  1. zrobić duży obiekt (mówiłeś 2M w komentarzu ... wtf ... wow) - 2M przydzielane w głównym wątku
  2. post do pracownika, 2M w główny wątek nadal, plus jakikolwiek dodatkowy został utworzony jako kłaczek w głównym wątku do JSONify twojego obiektu/tablicy, a następnie wyłączony do pracownika, gdzie 2M w pracownikach yay
  3. Chug na tym frajerem w pracowniku ... tutaj 2M + w głównym wątku siedzi po prostu czekając na GC, może się zdarzyć teraz, może nie ... GC uruchamia się po tym, jak pewna ilość obiektów nowej generacji osiągnie próg ... jak powiedz po lub w trakcie tworzenia mnóstwa nowych obiektów i elementów domowych: D
  4. Pracownik odpowiada, wysyłając wiadomość, pozwala założyć, że 2M jest teraz od nowa w głównym wątku dla nowego 2M (yay), a także wszystkie obiekty pamięci puszystej wymagane do de JSONify obiektu ... widzisz, gdzie to idzie.

Skoro powiedział, że był to aplikacja chrom (inny komentarz), a następnie być może można zrestrukturyzować swój kod do korzystania z Transferable Objects aby uniknąć tworzenia obiektu Klonowanie obiektów tymczasowych itp Oczywiście, aby korzystać z obiektów, które zbywalne Musiałby zrestrukturyzować się jako bufor tablicowy, a to jest mroczna magia sama w sobie.

+0

* "powiedziałeś 2M w komentarzu ... wtf ... wow" * - O wiele większe jest zwykle w przypadku aplikacji takich jak oprogramowanie graficzne, audio lub analityczne. Mijam tablice o rozmiarze 12 GB (!) Tutaj bez problemów używając transferables. –

+0

@JohnWeisz - Zgoda, ostatnio również rutynowo używam większych obiektów z WebAudio itp. Ale w drodze powrotnej maszyny z końca 2013 roku wydawało się, że dużo. Myślę, że jego rzeczywisty problem miał dużo więcej wspólnego z tworzeniem mnóstwa tymczasowych obiektów i jako część jego pętli lub twórców map ... nie mówiąc już o tym, co robił w DOM. –

Powiązane problemy