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?
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? –
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 –
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. –