SORU
25 Aralık 2012, Salı


JavaScript setınterval() yöntemi, bellek sızıntısına neden?

Şu anda JavaScript tabanlı animasyon bir proje geliştiriyor.

, setInterval(), setTimeout() ve hatta requestAnimationFrame doğru kullanımı talebim olmadan bellek ayırır, ve sık sık çöp toplama çağrıları neden olduğunu fark ettim. Daha = GC aramalar titriyor :-(

Aşağıdaki öldürdüğümde örneğin;basit bir kodınit arayarak (Google Chrome, bellek ayırma çöp toplama ilk 20-30 saniye için iyi

function init()
{
    var ref = window.setInterval(function() { draw(); }, 50);
}

function draw()
{
    return true
}

Bir şekilde, bir kaç dakika içinde, ayrılan bellek içinde garip bir artış başlıyor! Init beri() yalnızca bir kez denirayrılmış bellek boyutu artışın nedeni nedir?

(Edit: chrome ekran görüntüsü karşıya)

chrome screenshot

NOT #1: Evet, clearınterval aramayı denedim() sonraki setınterval önce). Sorun aynı kalır!

Sorunu izole etmek için, yukarıdaki kod basit ve aptalca tutuyorum. NOT #2:

CEVAP
25 Aralık 2012, Salı


EDİT: Yury's answer daha iyidir.


tl;bellek yok dr IMO sızıntısı. Pozitif eğim sadece setTimeout ve setınterval etkisi. Çöp yok bir bellek sızıntısı tanım olarak testere dişi desen, anlam tarafından görüldüğü gibi, toplanan. (Sanırım).

Sözde "bellek sızıntısı." bu sorunu çözmek için bir yol var emin değilim "Bellek sızıntısı" memory profiler. olumlu pistleri gözüyle setınterval fonksiyonu bellek kullanımını artırmak için her arama yönlendirme için, bu durumda,

Gerçeklik gerçek bellek sızıntısı yok: çöp toplayıcı, bellek toplamak mümkün. Tanım olarak bellek sızıntısı bellek bir bilgisayar programı satın aldı ama serbest bırakmak için başarısız olduğunda "işletim sistemi oluşur."

Aşağıda bellek profilleri ile gösterildiği gibi, bellek sızıntısı meydana değildir. Bellek kullanımı her işlev çağrısı ile artmaktadır. OP bu aynı işlevi çağrıldığını çünkü, bellek artırmak olmalı hayır umuyor. Ancak, bu durum böyle değil. Bellek her işlev çağrısı ile tüketilir. Sonunda, çöp, testere dişi deseni oluşturma toplanır.

Aralıklarla yeniden düzenleyerek bir kaç yol keşfettim, ve hepsi aynı testere dişi deseni bazı girişimlerde çöp toplama başvurular muhafaza gibi asla olmuyor neden olsa da) yol açar.

function doIt() {
    console.log("hai")
}

function a() {
    doIt();
    setTimeout(b, 50);
}
function b() {
    doIt();
    setTimeout(a, 50);
}

a();

http://fiddle.jshell.net/QNRSK/14/

function b() {
    var a = setInterval(function() {
        console.log("Hello");
        clearInterval(a);
        b();                
    }, 50);
}
b();

http://fiddle.jshell.net/QNRSK/17/

function init()
{
    var ref = window.setInterval(function() { draw(); }, 50);
}
function draw()
{
    console.log('Hello');
}
init();

http://fiddle.jshell.net/QNRSK/20/

function init()
{
    window.ref = window.setInterval(function() { draw(); }, 50);
}
function draw()
{
    console.log('Hello');
    clearInterval(window.ref);
    init();
}
init();​

http://fiddle.jshell.net/QNRSK/21/

Görünüşe göre setTimeout setInterval resmen Javascript parçaları (dolayısıyla v8 bir parçası değildir). Uygulama uygulayıcısı bırakılır. the implementation of setInterval and such in node.js bakmanı öneririm

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Paulo Bautista

    Paulo Bautis

    21 Aralık 2008
  • PhoneArena

    PhoneArena

    7 NİSAN 2006
  • Ralph Phillips

    Ralph Philli

    5 Aralık 2006