Bellek sorunlarını düzeltme

Kayce Baskler
Kayce Baskçalar

Bellek sızıntıları, bellek şişmesi ve sık çöp toplama işlemi gibi sayfa performansını etkileyen bellek sorunlarını bulmak için Chrome'u ve Geliştirici Araçları'nı nasıl kullanacağınızı öğrenin.

Özet

  • Chrome Görev Yöneticisi ile sayfanızın şu anda ne kadar bellek kullandığını öğrenin.
  • Zaman Çizelgesi kayıtları ile 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ıyla JS yığınınızda yeni anıların ne zaman ayrıldığını öğrenin.

Genel bakış

RAIL performans modeli çerçevesinde performans çalışmalarınızın odağı, kullanıcılarınız olmalıdır.

Bellek sorunları, genellikle kullanıcılar tarafından algılanabileceği için önemlidir. Kullanıcılar bellek sorunlarını aşağıdaki şekillerde algılayabilir:

  • Sayfa performansı zaman içinde giderek kötüleşir. Bu muhtemelen bellek sızıntısının bir belirtisidir. Bellek sızıntısı, sayfadaki bir hatanın sayfanın zaman içinde giderek daha fazla bellek kullanmasına neden olmasıdır.
  • Bir sayfanın performansı sürekli olarak kötüdür. Bu muhtemelen hafıza şişkinliği belirtisidir. Bellek şişmesi, bir sayfanın optimum sayfa hızı için gerekenden daha fazla bellek kullanmasıdır.
  • Bir sayfanın performansı gecikiyor veya sık sık duraklıyor gibi görünüyor. Bu muhtemelen atık toplama sürecinin sık bir belirtisi olabilir. Atık toplama, tarayıcının belleği geri kazanmasıdır. Bunun ne zaman olacağına tarayıcı karar verir. Koleksiyonlar sırasında tüm komut dosyası yürütme işlemi duraklatılır. Dolayısıyla, tarayıcı çok fazla çöp topluyorsa komut dosyası yürütme işlemi çok fazla duraklatılır.

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

Bellek sızıntısını tanımlamak kolaydır. Bir site gitgide daha fazla bellek kullanıyorsa bir sızıntı vardır. Ancak bellek şişkinliğini tespit etmek biraz daha zordur. Hangi durum "çok fazla bellek kullanma" kapsamına girer?

Farklı cihazlar ve tarayıcılar farklı özelliklere sahip olduğundan, burada sabit sayılar yok. Yüksek kaliteli bir akıllı telefonda da sorunsuz çalışan bir sayfa, düşük kaliteli bir akıllı telefonda kilitlenebilir.

Burada önemli olan 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 ardından bu cihazlarda sayfanızı test edin. Deneyimin sürekli olarak kötü olması, sayfa bu cihazların bellek özelliklerini aşıyor olabilir.

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

Bellek sorunu araştırmanızın 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 izlemedir.

  1. Görev Yöneticisi'ni açmak için Üst Karakter+Esc tuşlarına basın veya Chrome ana menüsüne gidin ve 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ğini etkinleştirin.

    JS belleğini etkinleştirme

Bu iki sütun, sayfanızın belleği nasıl kullandığıyla ilgili farklı bilgiler verir:

  • Bellek sütunu, yerel belleği temsil eder. DOM düğümleri yerel bellekte depolanır. Bu değer artıyorsa DOM düğümleri oluşturulur.
  • JavaScript Belleği sütunu, JS yığınını temsil eder. Bu sütunda iki değer bulunur. İlgilendiğiniz değer gerçek sayıdır (parantez içindeki sayı). Canlı sayı, sayfanızdaki erişilebilir nesnelerin ne kadar bellek kullandığını gösterir. Sayı artıyorsa yeni nesneler oluşturulmakta veya mevcut nesneler büyümektedir.

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

Performans panelini incelemenizin başka bir başlangıç noktası olarak da 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 yapın.

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

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 başvurulan düğmeye her basıldığında, belge gövdesine on bin div düğümü eklenir ve x dizisine bir milyon x karakterden oluşan bir dize aktarılır. Bu kod çalıştırıldığında aşağıdaki ekran görüntüsüne benzer bir Zaman Çizelgesi kaydı oluşturulur:

basit büyüme örneği

İlk olarak, kullanıcı arayüzünün açıklaması. Genel Bakış bölmesindeki (NET'in altında) HEAP grafiği, JS yığınını temsil eder. Genel Bakış bölmesinin altında Sayaç bölmesi bulunur. Burada, JS yığınına (Genel Bakış bölmesindeki HEAP grafiğiyle aynıdır), belgelere, DOM düğümlerine, işleyicilere ve GPU belleğine göre ayrılmış bellek kullanımını görebilirsiniz. Bir onay kutusu devre dışı bırakıldığında grafikte gizlenir.

Şimdi, ekran görüntüsüyle karşılaştırıldığında kodun analizi. Düğüm sayacına (yeşil grafik) bakarsanız kodla kusursuz bir şekilde eşleştiğini görebilirsiniz. Düğüm sayısı farklı adımlarda artar. Düğüm sayısındaki her artışın bir grow() çağrısı 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 çöp toplama işlemidir (çöp topla düğmesine basılarak elde edilir). Kayıt ilerledikçe JS yığın boyutunun ani bir şekilde yükseldiğini görebilirsiniz. Bu, doğal ve beklenen bir durumdur: JavaScript kodu, her düğme tıklamasında DOM düğümlerini oluşturur ve bir milyon karakterden oluşan dize oluşturduğunda büyük bir iştir. Buradaki önemli nokta, JS yığınının başlangıçtan daha yüksekte bitmesidir (buradaki "başlangıç" zorunlu çöp toplama işleminden sonraki noktadır). Gerçek dünyada, JS yığın boyutunun veya düğüm boyutunun bu şekilde arttığını görürseniz bu durum muhtemelen bellek sızıntısı olduğu anlamına gelir.

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

DOM düğümleri, yalnızca sayfanın DOM ağacından veya JavaScript kodundan hiçbir referans olmadığında çöp toplama işlemi gerçekleştirilebilir. Bir düğümün DOM ağacından kaldırıldığında "ayrılmış" olduğu söylenir, ancak bazı JavaScript yine de bu düğüme referansta bulunur. Ayrılan DOM düğümleri, bellek sızıntılarının yaygın bir nedenidir. Bu bölümde, ayrılmış düğümleri tanımlamak için Geliştirici Araçları'nın yığın profili araçlarını nasıl kullanacağınız öğretilmektedir.

Ayrılan DOM düğümlerine dair basit bir örnek aşağıda 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 başvurulan düğme tıklandığında, on li alt öğesi olan bir ul düğümü oluşturulur. Bu düğümlere kod tarafından referans verilir ancak DOM ağacında yer almazlar. Bu nedenle düğümler ayrılır.

Yığın anlık görüntüleri, ayrılmış düğümleri tanımlamanın bir yoludur. Adından da anlaşılacağı gibi, yığın anlık görüntüleri, anlık görüntü anında belleğin sayfanızın 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 Geliştirici Araçları'nı açıp Bellek paneline gidin, Yığın Anlık Görüntüsü radyo düğmesini seçin ve 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ıktan sonra, soldaki panelden bu öğeyi seçin (HEAP SNAPSHOTS olarak adlandırılmıştır).

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

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

Bağımsız bir ağacı incelemek için karatları genişletin.

ayrılmış ağaç araştırılıyor

Sarı olarak vurgulanan düğümler, JavaScript kodundan bunlara doğrudan referansları vardır. Kırmızıyla vurgulanan düğümlerin doğrudan referansları yoktur. Sarı düğümdeki ağacın bir parçası oldukları için canlıdırlar. Genel olarak, sarı düğümlere odaklanmak istersiniz. Sarı düğümün gerekenden daha uzun süre aktif olmaması için kodunuzu düzeltin. Ayrıca, sarı düğümün ağacındaki kırmızı düğümleri de çıkarabilirsiniz.

Daha fazla araştırmak için sarı bir düğümü tıklayın. Nesneler bölmesinde, buna başvuruda bulunan 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 incelemeniz ve artık gerekli olmadığında düğüme yönelik referansını kaldırdığınızdan emin olmanız gerekir.

sarı düğümü araştırıyor

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

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 Çizelgesi'ni göstermek için aşağıdaki kodu göz önünde bulundurun:

var x = [];

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

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

Kodda başvurulan düğme her aktarıldığında x dizisine bir milyon karakterden oluşan bir dize eklenir.

Ayırma Zaman Çizelgesi'ni kaydetmek için Geliştirici Araçları'nı açın, Profiller paneline gidin, Kayıt Zaman Çizelgesi radyo düğmesini seçin, Başlat düğmesine basın, 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, Ayırma Zaman Çizelgesi'nde aşağıdaki ekran görüntüsündeki gibi mavi çubukların görünüp görünmediğine dikkat edin.

yeni tahsisler

Bu mavi çubuklar yeni bellek ayırmalarını gösterir. Bu yeni bellek ayırmaları, bellek sızıntıları için adaylarınızdır. Bir çubuğu yakınlaştırarak Oluşturucu bölmesini yalnızca belirtilen zaman aralığında ayrılmış nesneleri gösterecek şekilde filtreleyebilirsiniz.

yakınlaştırılmış ayırma zaman çizelgesi

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

nesne ayrıntıları

İşleve göre bellek ayırmayı inceleme

JavaScript işlevine göre bellek ayırmayı görüntülemek için Bellek panelindeki Atama Örneklemesi türünü kullanın.

Kayıt Ayırma Profil Aracını

  1. Atama Örneklemesi 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 sayfada ilgili işlemleri gerçekleştirin.
  4. Tüm işlemlerinizi tamamladığınızda Durdur düğmesine basın.

Geliştirici Araçları, bellek ayırmanın işleve göre dökümünü gösterir. Varsayılan görünüm Yoğun (Aşağıdan Yukarı) görünümü, en fazla belleği en üstte ayıran işlevleri gösterir.

Ayırma profili

Sık sık çöp toplama noktalarını tespit etme

Sayfanız sık sık duraklatılıyorsa çöp toplama sorunları yaşıyor olabilirsiniz.

Sık sık çöp toplama işlemlerini 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 yükselen ve azalan Bellek veya JavaScript Belleği değerleri sık sık çöp toplama işlemini temsil eder. Zaman Çizelgesi kayıtlarındaki sıklıkla yükselen ve düşen JS yığın veya düğüm sayısı grafikleri, sık çöp toplama işlemi yapıldığını gösterir.

Sorunu tanımladıktan sonra, belleğin nereye ayrıldığını ve ayırmalara hangi işlevlerin neden olduğunu öğrenmek için Ayırma Zaman Çizelgesi kaydı kullanabilirsiniz.