SORU
22 EYLÜL 2009, Salı


jQuery DOM hafıza temizleme ile sızıntı

İşte sızıntı IE8 bellek jQuery kullanarak ölü-basit bir web sayfası (iexplore.exe benim süreç bellek kullanımı zamanla Windows izleyerek bellek sızıntısı tespit ettim Görev Yöneticisi):

<html>
<head>
    <title>Test Page</title>
    <script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<script type="text/javascript">
    function resetContent() {
        $("#content div").remove();
        for(var i=0; i<10000; i  ) {
            $("#content").append("<div>Hello World!</div>");
        }
        setTimeout(resetTable, 2000);
    }
    $(resetContent);
</script>
<div id="content"></div>
</body>
</html>

jQuery.remove() işlevi çağrılırken bile hala bazı bellek sızıntısı deneyim anlaşılan. Yazdım, hayır bellek aşağıdaki gibi sızıntı yaşandığı işlevi ortadan kaldırabilirim

$.fn.removeWithoutLeaking = function() {
    this.each(function(i,e){
        if( e.parentNode )
            e.parentNode.removeChild(e);
    });
};

Bu gayet iyi çalışıyor ve herhangi bir bellek sızıntısı yok. Neden jQuery bellek sızıntısı? Başka bir fonksiyonu jQuery.remove() dayalı kaldırmak oluşturdum ve bu gerçekten bir sızıntı neden olur:

$.fn.removeWithLeakage = function() {
    this.each(function(i,e) {
        $("*", e).add([e]).each(function(){
            $.event.remove(this);
            $.removeData(this);
        });
        if (e.parentNode)
            e.parentNode.removeChild(e);
    });
};

İlginçtir, bellek sızıntısı jQuery olayları ve veri DOM öğeleri siliniyor ile ilgili bellek sızıntıları önlemek için içeren her çağrı neden gibi görünüyor. removeWithoutLeaking fonksiyonu çağırdığımda sonra hafızamı sürekli zaman içinde kalır, ama removeWithLeakage aradığımda bunun yerine daha sonra sürekli uzuyor.

Benim sorum her çağrının ne demeli

$("*", e).add([e]).each(function(){
    $.event.remove(this);
    $.removeData(this);
});

muhtemelen bellek sızıntısına neden olabilir mi?

EDİT:, yeniden test etmesi üzerine, sonuçları üzerinde hiçbir etkisi kanıtlanmış olan kod yazım hatası Düzeltildi.

DAHA da EDİT: bu bir WordPress kullanmak bir hata gibi görünüyor beri: jQuery proje ile bir hata raporu açtı, ben http://dev.jquery.com/ticket/5285

CEVAP
23 EYLÜL 2009, ÇARŞAMBA


David sözde removeChild sızıntı ile bir şeyin peşinde olabilir diye düşündüm, ama IE8... önceki tarayıcılar olabilir, ama biz burada öyle bir şey değil çoğalır edemem. Ben el ile divs var removeChild ise hiçbir sızıntı; eğer değiştirdiğim takdirde outerHTML= '' kullanmak için bir WordPress kullanmak (veya taşımak bin bin izledi.innerHTML) removeChild yerine hala bir sızıntı var.

Eleme süreci içinde bir WordPress kullanmak remove bit hack başladım. çizgi 1.3.2 1244 yılında:

//jQuery.event.remove(this);
jQuery.removeData(this);

Bu satır Yorum yok kaçak sonuçlandı.

Bakalım olay bak.kaldırmak, data('events') eğer herhangi bir olay elementi bağlı olup olmadığını görmek için çağırır. data ne yapıyor?

// Compute a unique ID for the element
if ( !id )
    id = elem[ expando ] =   uuid;

Oh. Bir WordPress kullanmak bir uuıd veri-arama giriş özellikleri hack bile dener her eleman için eklemeokuyunkaldırıyorsun bir elementin her bir torunu içeren veri,! Ne kadar saçma. Sadece daha önce bu satırı koyarak kısa devre yapacağım:

// Don't create ID/lookup if we're only reading non-present data
if (!id && data===undefined)
    return undefined;

IE8 bu durumda sızıntıyı tamir etmek için görünür. Bir WordPress kullanmak olduğunu labirent başka bir sonu olmayacak garanti edemez, ama mantıklı mantıklı.

Bildiğim kadarıyla söyleyebilirim, sızıntının sadece jQuery.cache Nesne (veri deposu değil, gerçekten bir önbellek gibi) gittikçe daha büyük ve daha büyük olarak yeni bir anahtar eklendi için her öğe kaldırıldı. RemoveData bu önbellek girdilerini kaldırma TAMAM olmalıdır rağmen, YANİ 23 ** bir Nesne anahtarı ne zaman alanını kurtarmak için görünmüyor.

(Her iki şekilde de, bu hoşuma gitmiyor jQuery davranış şekli bir örnektir. Çok şüpheli şeyler oldukça biraz basit basit bir işlem... ne olması gerektiği için bu başlık altında yapıyor. Bu expando ve what jQuery does to innerHTML via regex to prevent that showing as an attribute in IE ile her şey bozuk ve çirkin. Ve alıcı yapmak ve aynı işlevi ayarlayıcı alışkanlığı kafa karıştırıcı ve, burada, bu hata oluşur.)

[Tuhaf bir şekilde ayrılan leaktest için uzun süre zaman sona erdi zaman zaman vererek tamamen sahte hataları jquery.js önce bellek gerçekten bitti... bir şey vardı gibi ‘beklenmedik komut’, ve Ben Ünlü bir ‘düğümadı null) veya bir nesne’ at line 667, hangi kadar görebiliyorum zaten hep koşmak şöyle dursun, orada bir kontrol için nodeName olmak boş! YANİ bana pek güven vermiyor işte...]

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • dougownsall

    dougownsall

    7 EKİM 2007
  • EmmightySofia

    EmmightySofi

    25 EYLÜL 2011
  • Visual Life

    Visual Life

    3 Temmuz 2006