Jednym z reklamowany zalet jQuery.data porównaniu surowych właściwości EXPANDO (arbitralnych atrybutów można przypisać do węzłów DOM) jest to, że jQuery.data jest „bezpieczny z odniesieniami okrągłych i dlatego wolne od wycieków pamięci”. Artykuł z Google zatytułowany "Optimizing JavaScript code" przechodzi w bardziej szczegółowo:Dokładne wyjaśnienie JavaScript <-> DOM emisji okrągły odniesienia
Najczęstszymi wycieki pamięci dla aplikacji internetowych wiąże okrągłe odniesień między silnikiem skryptów JavaScript i C++ obiektów przeglądarek wykonawczego DOM (np pomiędzy JavaScript skrypt silnik i infrastruktura COM przeglądarki Internet Explorer lub między silnikiem JavaScript i Firefox XPCOM).
Wymienia dwa przykłady kształtach odniesienia:
elementu DOM → obsługi zdarzeń zakres → zamknięcie → DOM
elementu DOM → poprzez EXPANDO → pośredni Przedmiotem → elementu DOM
Jeśli jednak cykl odniesienia między węzłem DOM a obiektem JavaScript powoduje przeciek pamięci, nie oznacza to, że nie jest trywialna procedura obsługi zdarzeń (np. onclick
) spowoduje taki wyciek? I nie rozumiem, jak to w ogóle możliwe dla obsługi zdarzeń, aby uniknąć cyklu odniesienia, bo tak jak ja to widzę:
Element DOM odwołuje się do procedury obsługi zdarzeń.
Program obsługi zdarzeń odwołuje się do DOM (bezpośrednio lub pośrednio). W każdym razie prawie niemożliwe jest uniknięcie odniesienia do
window
w jakiejkolwiek interesującej procedurze obsługi zdarzenia, poza zapisem pętlisetInterval
odczytującej akcje z globalnej kolejki.
Czy ktoś może podać dokładne wyjaśnienie problemu z kodem JavaScript DOM ↔ DOM? Rzeczy, które chciałbym wyjaśnić:
Jakie przeglądarki są wykonywane? Komentarz w źródle jQuery wyraźnie wspomina o IE6-7, ale artykuł Google sugeruje, że dotyczy to również Firefoksa.
Czy właściwości expando i programy do obsługi zdarzeń są w jakiś sposób różne w przypadku wycieków pamięci? A może oba te fragmenty kodu są podatne na ten sam wyciek pamięci?
// Create an expando that references to its own element. var elem = document.getElementById('foo'); elem.myself = elem; // Create an event handler that references its own element. var elem = document.getElementById('foo'); elem.onclick = function() { elem.style.display = 'none'; };
Jeśli pamięć przecieki strona powodu okrągłej odniesienia, czy wyciek nie ustąpią, dopóki cała aplikacja przeglądarka jest zamknięta, czy pamięć jest zwolniona, gdy okno/karta jest zamknięta?
Czy ten kod naprawdę spowodował wyciek pamięci? Nie rozumiem dlaczego. var elem = document.getElementById ('foo'); elem.myself = elem; – CEGRD