Bellek sorunlarını düzeltme

Chrome ve Geliştirici Araçları'nı kullanarak bellek sızıntıları, bellek patlaması ve sık atık toplama gibi sayfa performansını etkileyen bellek sorunlarını nasıl bulacağınızı öğrenin.

Özet

  • Chrome Görev Yöneticisi'ni kullanarak sayfanızın şu anda ne kadar bellek kullandığını öğrenin.
  • Zaman çizelgesi kayıtlarıyla zaman içindeki bellek kullanımını görselleştirin.
  • Yığın Anlık Görüntüleri ile ayrılmış DOM ağaçlarını (bellek sızıntılarının yaygın bir nedeni) tanımlayın.
  • Ayırma Zaman Çizelgesi kayıtları ile JS yığınınıza ne zaman yeni bellek ayrıldığını öğrenin.

Genel Bakış

RAIL performans modelinin ruhuna uygun olarak, performans çalışmalarınızda kullanıcılarınıza odaklanmanız gerekir.

Hafıza sorunları, genellikle kullanıcılar tarafından fark edilebildiği için önemlidir. Kullanıcılar bellek sorunlarını şu şekillerde algılayabilir:

  • Sayfanın performansı zaman içinde giderek kötüleşiyor. Bu durum, muhtemelen hafıza sızıntısının bir belirtisidir. Bellek sızıntısı, sayfadaki bir hatanın sayfanın zaman içinde kademeli olarak daha fazla bellek kullanmasına neden olması anlamına gelir.
  • Sayfanın performansı sürekli olarak kötüdür. Bu muhtemelen hafızada şişkinlik belirtisidir. Bellek şişmesi, bir sayfanın optimum sayfa hızı için gerekenden daha fazla bellek kullanmasıdır.
  • Sayfanın performansı gecikiyor veya sık sık duraklatılıyor. Bu muhtemelen sık sık çöplerin toplanmasından kaynaklanabilir. Çöp toplama, tarayıcının belleği geri almasıdır. Bunun ne zaman olacağına tarayıcı karar verir. Koleksiyonlar sırasında tüm komut dosyası yürütme duraklatılır. Bu nedenle, tarayıcı çok fazla çöp topluyorsa komut dosyası yürütme çok sık duraklatılır.

Bellek şişmesi: "Çok fazla" ne kadar?

Bellek sızıntısını tanımlamak kolaydır. Bir site giderek daha fazla bellek kullanıyorsa bellek sızıntısı vardır. Ancak hafıza yetersizliğini sabitlemek biraz daha zordur. Neler "çok fazla bellek kullanımı" kapsamına girer?

Farklı cihazlar ve tarayıcılar farklı becerilere sahip olduğundan, burada kesin sayı yoktur. İleri teknoloji akıllı telefonlarda sorunsuz çalışan aynı sayfa, gelişmiş teknoloji akıllı telefonlarda kilitlenebilir.

Buradaki anahtar, RAIL modelini kullanmak ve kullanıcılarınıza odaklanmaktır. Kullanıcılarınız arasında hangi cihazların popüler olduğunu öğrenin ve sayfanızı bu cihazlarda test edin. Deneyim sürekli olarak kötüyse sayfa, bu cihazların bellek kapasitesini aşıyordur.

Chrome Görev Yöneticisi ile bellek kullanımını gerçek zamanlı olarak izleme

Bellek sorunuyla ilgili incelemenizin başlangıç noktası olarak Chrome Görev Yöneticisi'ni kullanın. Görev Yöneticisi, bir sayfanın şu anda ne kadar bellek kullandığını gösteren gerçek zamanlı bir izleyicidir.

  1. Görev Yöneticisi'ni açmak için Üst Karakter+Esc tuşlarına basın veya Chrome ana menüsüne gidip Diğer araçlar > Görev Yöneticisi'ni seçin.

    Görev Yöneticisi'ni açma

  2. Görev Yöneticisi'nin tablo başlığını sağ tıklayın ve JavaScript belleği'ni etkinleştirin.

    JS belleğini etkinleştirme

Bu iki sütun, sayfanızı belleğin nasıl kullandığı hakkında farklı bilgiler verir:

  • Bellek sütunu, yerel belleği temsil eder. DOM düğümleri yerel bellekte saklanır. Bu değer artıyorsa DOM düğümleri oluşturuluyor demektir.
  • JavaScript Bellek sütunu, JS yığınını temsil eder. Bu sütunda iki değer yer alır. İlgilendiğiniz değer, canlı sayı (parantez içindeki sayı) olur. Yayındaki sayı, sayfanızdaki erişilebilir nesnelerin ne kadar bellek kullandığını gösterir. Bu sayı artıyorsa yeni nesneler oluşturuluyor veya mevcut nesneler büyüyor demektir.

Performans kayıtlarıyla bellek sızıntılarını görselleştirme

İncelemenizde başka bir başlangıç noktası olarak Performans panelini de kullanabilirsiniz. Performans paneli, bir sayfanın zaman içindeki bellek kullanımını görselleştirmenize yardımcı olur.

  1. Geliştirici Araçları'nda Performans panelini açın.
  2. Bellek onay kutusunu etkinleştirin.
  3. Kayıt yapma

Performans belleği kayıtlarını göstermek için aşağıdaki kodu inceleyin:

var x = [];

function grow() {
  for (var i = 0; i < 10000; i++) {
    document.body.appendChild(document.createElement('div'));
  }
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

Kodda referans verilen düğmeye her basıldığında doküman gövdesine on bin div düğümü eklenir ve x dizisine bir milyon x karakterlik bir dize aktarılır. Bu kodu çalıştırdığınızda aşağıdaki ekran görüntüsüne benzer bir Zaman Çizelgesi kaydı oluşturulur:

basit büyüme örneği

Öncelikle kullanıcı arayüzünü açıklayalım. Genel bakış bölmesinde (NET'in altında) bulunan HEAP grafiği, JS yığınını temsil eder. Genel Bakış bölmesinin altında Sayaç bölmesi bulunur. JS yığınına (Genel Bakış bölmesindeki HEAP grafiğinde olduğu gibi), dokümanlara, DOM düğümlerine, işleyicilere ve GPU belleğine göre ayrılmış bellek kullanımını görebilirsiniz. Devre dışı bırakılan onay kutuları grafikte gizlenir.

Şimdi, ekran görüntüsüyle karşılaştırmalı olarak kodun analizini göreceğiz. Düğüm sayıcıya (yeşil grafik) bakarsanız kodun düzgün bir şekilde eşleştiğini görebilirsiniz. Düğüm sayısı ayrı adımlarla artar. Düğüm sayısındaki her artışın grow() için bir çağrı olduğunu varsayabilirsiniz. JS yığın grafiği (mavi grafik) o kadar basit değildir. En iyi uygulamalara uygun olarak, ilk düşüş aslında zorunlu bir atık toplama işlemidir (Atık topla düğmesine basılarak yapılır). Kayıt ilerledikçe JS yığın boyutunun yükseldiğini görebilirsiniz. Bu durum doğal ve beklenen bir durumdur: JavaScript kodu, her düğme tıklamasında DOM düğümlerini oluşturur ve bir milyon karakterlik dize oluştururken çok fazla iş yapar. Buradaki en önemli nokta, JS yığınının başlangıcından daha yüksek bir şekilde bitmesidir (buradaki "başlangıç", zorunlu atık toplama işleminden sonraki noktadır). Gerçek dünyada, JS yığın boyutunun veya düğüm boyutunun arttığı bu kalıbı görürseniz muhtemelen bellek sızıntısı söz konusudur.

Yığın anlık görüntüleriyle ayrılmış DOM ağacı bellek sızıntılarını keşfetme

Bir DOM düğümü yalnızca sayfanın DOM ağacından veya JavaScript kodundan kendisine referans olmadığında çöp toplanabilir. Bir düğümün DOM ağacından kaldırılması durumunda bu düğümün "ayrılmış" olduğu söylenir, ancak bazı JavaScript kodları bu düğüme referansta bulunmaya devam eder. Ayrılmış DOM düğümleri, hafıza sızıntılarının yaygın bir nedenidir. Bu bölümde, ayrılmış düğümleri tanımlamak için DevTools'un yığın profilleyicilerini nasıl kullanacağınız açıklanmaktadır.

Aşağıda, çıkarılan DOM düğümlerine ilişkin basit bir örnek verilmiştir.

var detachedTree;

function create() {
  var ul = document.createElement('ul');
  for (var i = 0; i < 10; i++) {
    var li = document.createElement('li');
    ul.appendChild(li);
  }
  detachedTree = ul;
}

document.getElementById('create').addEventListener('click', create);

Kodda atıfta bulunulan düğmeye tıklandığında on li alt öğesi olan bir ul düğümü oluşturulur. Bu düğümler kod tarafından referans gösterilir ancak DOM ağacında bulunmadığından ayrılır.

Ayrılmış düğümleri belirlemenin bir yolu yığın anlık görüntüleridir. Adından da anlaşılacağı gibi, yığın anlık görüntüleri, anlık görüntü sırasında belleğin JS nesneleri ve DOM düğümleri arasında nasıl dağıtıldığını gösterir.

Anlık görüntü oluşturmak için DevTools'u açıp Bellek paneline gidin, Yığın Anlık Görüntüsü radyo düğmesini seçin ve ardından Anlık Görüntü Al düğmesine basın.

yığın anlık görüntüsü al

Anlık görüntünün işlenmesi ve yüklenmesi biraz zaman alabilir. İşlem tamamlandığında sol panelden (HEAP SNAPSHOTS (Yığın anlık görüntüleri) adlı) seçin.

Ayrılmış DOM ağaçları aramak için Sınıf filtresi metin kutusuna Detached yazın.

Ayrılmış düğümler için filtreleme

Ayrılan ağacı araştırmak için karatları genişletin.

ayrılmış ağacı inceleme

Sarıyla vurgulanan düğümler, JavaScript kodundan bunlara doğrudan referans veriyor. Kırmızıyla vurgulanan düğümlerin doğrudan referansı yoktur. Sadece sarı düğümün ağacının bir parçası oldukları için canlıdırlar. Genel olarak sarı düğümlere odaklanmanız gerekir. Sarı düğümün olması gerekenden daha uzun süre yayında kalması için kodunuzu düzeltin. Böylece, sarı düğüm ağacının parçası olan kırmızı düğümlerden de kurtulmuş olursunuz.

Daha ayrıntılı incelemek istediğiniz sarı düğümleri tıklayın. Nesneler bölmesinde, buna referans veren kod hakkında daha fazla bilgi görebilirsiniz. Örneğin, aşağıdaki ekran görüntüsünde detachedTree değişkeninin düğüme referans verdiğini görebilirsiniz. Bu bellek sızıntısını düzeltmek için detachedTree kullanan kodu inceleyip artık gerekli olmadığında düğüme referansını kaldırdığından emin olursunuz.

Sarı bir düğümü inceleme

Ayırma Zaman Çizelgeleri ile JS yığın bellek sızıntılarını belirleme

Ayırma Zaman Çizelgesi, JS yığınınızdaki bellek sızıntılarını izlemenize yardımcı olabilecek başka bir araçtır.

Ayırma Zaman Çizelgesini göstermek için aşağıdaki kodu inceleyin:

var x = [];

function grow() {
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

Kodda referans verilen düğmeye her basıldığında x dizisine bir milyon karakterlik bir dize eklenir.

Ayırma Zaman Çizelgesi kaydetmek için Geliştirici Araçları'nı açın, Profiller paneline gidin, Ayırma Zaman Çizelgesini Kaydet radyo düğmesini seçin, Başlat düğmesine basın ve bellek sızıntısına neden olduğundan şüphelendiğiniz işlemi gerçekleştirin ve işiniz bittiğinde kaydı durdur düğmesine (Kaydı durdur düğmesi) basın.

Kayıt sırasında, aşağıdaki ekran görüntüsündeki gibi Ayırma Zaman Çizelgesi'nde mavi çubuklar olup olmadığına dikkat edin.

yeni tahsisler

Bu mavi çubuklar, yeni bellek ayırmalarını gösterir. Bu yeni bellek atamalarının, bellek sızıntısı olasılığı taşıyan alanlar olduğunu unutmayın. Oluşturucu bölmesini yalnızca belirtilen zaman aralığında ayrılan nesneleri gösterecek şekilde filtrelemek için bir çubuğu yakınlaştırabilirsiniz.

yakınlaştırılmış tahsis zaman çizelgesi

Nesneyi genişletin ve Nesne bölmesinde onunla ilgili daha fazla ayrıntı görüntülemek için değerini tıklayın. Örneğin, aşağıdaki ekran görüntüsünde yeni atanan nesnenin ayrıntılarını görüntüleyerek Window kapsamındaki x değişkenine atandığını görebilirsiniz.

nesne ayrıntıları

Bellek tahsisini işleve göre inceleme

JavaScript işlevine göre bellek tahsisini görüntülemek için Bellek panelindeki Tahsis Örnekleme türünü kullanın.

Ayırma Profil Aracını Kaydet

  1. Ayrıntılandırma Örnekleme radyo düğmesini seçin. Sayfada bir çalışan varsa Başlat düğmesinin yanındaki açılır menüyü kullanarak bunu profil oluşturma hedefi olarak seçebilirsiniz.
  2. Başlat düğmesine basın.
  3. İncelemek istediğiniz sayfadaki işlemleri gerçekleştirin.
  4. Tüm işlemlerinizi tamamladığınızda Durdur düğmesine basın.

DevTools, bellek tahsisinin işleve göre dökümünü gösterir. Varsayılan görünüm Yoğun (Aşağıdan Yukarı), en çok bellek ayıran işlevleri en üstte gösterir.

Ayırma profili

Sık atık toplama noktalarını tespit etme

Sayfanız sık sık duraklıyor gibi görünüyorsa atık toplamayla ilgili sorun yaşıyor olabilirsiniz.

Sık sık çöp toplama işlemi yapıldığını tespit etmek için Chrome Görev Yöneticisi'ni veya Zaman Çizelgesi bellek kayıtlarını kullanabilirsiniz. Görev Yöneticisi'nde sık sık yükselip düşen Bellek veya JavaScript Bellek değerleri, sık sık çöp toplama işlemi yapıldığını gösterir. Zaman çizelgesi kayıtlarında, JS yığın veya düğüm sayısı grafiklerinin sık sık yükselip düşmesi sık sık çöp toplama işlemi yapıldığını gösterir.

Sorunu tespit ettikten sonra, belleğin nereye ayrıldığını ve hangi işlevlerin bu ayarlamalara neden olduğunu öğrenmek için bir Ayırma Zaman Çizelgesi kaydını kullanabilirsiniz.