2009-04-20 13 views
27

Mam aplikację, która pozwala użytkownikowi przeglądać szczegółowe informacje o konkretnym przypadku bez podsumowania. Za każdym razem, gdy użytkownik żąda danych z serwera, wyciągam następujące znaczniki.Jak pozbyć się elementów DOM w JavaScript, aby uniknąć wycieków pamięci?

<form name="frmAJAX" method="post" action="Default.aspx?id=123456" id="frmAJAX"> 
<div> 
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" /> 
</div> 
<div> 
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" /> 
</div> 
<div id="inner"> 
<!-- valid info here --!> 
</div> 
</form> 

Następny biorę powyżej InnerHTML go do nowego elementu DOM tak:

success: function(xhtml) { 
     var tr = document.createElement('tr'); 
     var td = document.createElement('td'); 
     var container = document.createElement('div'); 

     obj.parentNode.parentNode.parentNode.insertBefore(tr, obj.parentNode.parentNode.nextSibling); 

     td.appendChild(container); 
     container.innerHTML = xhtml; 
     tr.appendChild(td); 

ale po wyżej, używam niektóre jQuery do usuwania nieprzyjemnych aspnet Junk

$('form:eq(1)').children().each(
    function() { 
     if ($('form:eq(1)').find('div').filter(function() { return $(this).attr('id') == ''; }).remove()); 
    } 
); 

//Capture the remaining children 
var children = $('form:eq(1)').children(); 

// Remove the form 
$('form:eq(1)').remove(); 

// append the correct child element back to the DOM 
parentObj.append(children); 

Moje pytanie brzmi - podczas korzystania z IESieve nie zauważam faktycznych przecieków, ale ciągle rosnącą liczbę elementów DOM (a więc wykorzystanie pamięci).

Co mogę poprawić po stronie klienta, aby rzeczywiście oczyścić ten bałagan? Uwaga - oba IE7/8 pokazują te wyniki.

EDIT: I w końcu udało się tej pracy i postanowiłem napisać krótki blog post z pełnym kodem źródłowym.

+0

Należy naprawdę zaakceptować odpowiedź na to pytanie teraz .... – Blazemonger

+0

można zaktualizować URL blogu post? – Christian

+1

@ Christians po prostu (przepraszam za zepsuty link) –

Odpowiedz

12

Trudną częścią jest ustalenie, gdzie istnieje odniesienie do węzłów naruszających prawa.

Robisz to na swój sposób - dodajesz wszystkie znaczniki do strony, a następnie usuwasz rzeczy, których nie chcesz. Zrobiłbym to w ten sposób:

var div = document.createElement('div'); 
// (Don't append it to the document.) 

$(div).html(xhtml); 

var stuffToKeep = $(div).find("form:eq(1)> *").filter(
    function() { 
    return $(this).attr('id') !== ''; 
    } 
); 

parentObj.append(stuffToKeep); 

// Then null out the original reference to the DIV to be safe. 
div = null; 

Nie ma gwarancji zatrzymania wycieku, ale to dobry początek.

+0

To duży krok naprzód, ponieważ większość elementów DOM, które po prostu się kręci, to te, które usuwałam i nigdy ich nie używałam. Dziękuję Ci! –

2

remove() i jej ilk tylko usunąć elementy z DOM. Wciąż istnieją w pamięci.

Jest to znany problem z AJAX i Web 2.0. Niewiele możesz zrobić, oprócz projektowania witryny, aby od czasu do czasu odświeżyć stronę, aby usunąć zawartość.

+3

Nie możesz ich pozbyć w taki sposób, że gdy pojawi się javascript garbage collector, elementy są usuwane z pamięci? –

+0

Można założyć, że tak jest, ale najwyraźniej tak nie jest. – Randolpho

+2

Hmm ... po pewnym kopaniu możesz wypróbować niektóre rozwiązania omówione na tej stronie: http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/c76967f0-dcf8-47d0-8984 -8fe1282a94f5 – Randolpho

1

Myślę, że "stale rosnące zużycie pamięci" jest nieco źle rozumiane. Ma to związek z zarządzaniem pamięcią w przeglądarce (a także w systemie Windows w ogóle) bardziej niż z kodem JS. Menedżerowie pamięci zazwyczaj przydzielają (lub unikają zwalniania), dopóki nie będą musieli. W systemach opartych na plikach stron i mapowaniu pamięci przydzielanie i zwalnianie pamięci jest bardzo czasochłonne.

Więc nawet jeśli twoje węzły są zwolnione z rzeczywistej struktury dokumentu i DOM - prawie nie da się zmierzyć go z samego systemu Windows w "czasie rzeczywistym".

Spróbuj tego:

  1. start Taskmanager, przełącznik do przetwarzania kartę i oglądać pamięci twojej przeglądarki

  2. ładunek w dokumencie HTML, który przydziela 100.000 węzłów obserwować zużycie pamięci rosną

  3. Kliknij przycisk na stronie, która zwalnia wszystkie węzły. Zauważ, że niewiele dzieje się w kwestii uwolnienia pamięci.

  4. Teraz zminimalizuj okno przeglądarki i zmaksymalizuj je ponownie.W 90% przypadków przeglądarka zrzuca teraz pamięć, jeśli jej nie używa, a zobaczysz, ile naprawdę zużywa.

Można mieć przeglądarka zużywają 500 megabajtów pamięci RAM (nie wyżej przykład), ale podczas minimalizowania i maksymalizowania ją, uwalnia wszystko i nagle używa tylko 50 megabajtów.

6
function discardElement(element) { 
    var garbageBin = document.getElementById('IELeakGarbageBin'); 
    if (!garbageBin) { 
     garbageBin = document.createElement('DIV'); 
     garbageBin.id = 'IELeakGarbageBin'; 
     garbageBin.style.display = 'none'; 
     document.body.appendChild(garbageBin); 
    } 
    // move the element to the garbage bin 
    garbageBin.appendChild(element); 
    garbageBin.innerHTML = ''; 
} 

Source

+0

Wiem, że jest trochę za późno w grze ... –

+2

Taki piękny przykład, dlaczego IE jest do bani ... –

+2

nie podajecie żadnego wyjaśnienia, dlaczego tak się stanie. to nie ma sensu. – vsync