Yığın anlık görüntüleri kaydet

Meggin Kearney
Meggin Kearney
Sofia Emelianova
Sofia Emelianova

Bellek > Profiller > Yığın anlık görüntüsü'nü kullanarak yığın anlık görüntülerini nasıl kaydedeceğinizi ve bellek sızıntısı bulup bulmadığınızı öğrenin.

Yığın profili, sayfanızdaki JavaScript nesneleri ve ilgili DOM düğümlerine göre bellek dağılımını gösterir. JS yığın anlık görüntüleri almak, bellek grafiklerini analiz etmek, anlık görüntüleri karşılaştırmak ve bellek sızıntılarını bulmak için kullanın. Daha fazla bilgi için Nesneleri saklayan ağaç başlıklı makaleyi inceleyin.

Anlık görüntü alma

Yığın anlık görüntüsü almak için:

  1. Profil oluşturmak istediğiniz bir sayfada Geliştirici Araçları'nı açın ve Bellek paneline gidin.
  2. Yığın anlık görüntüsü profilleme türünü seçin, ardından bir JavaScript VM örneği seçin ve Anlık görüntü al'ı tıklayın.

Seçilen bir profil oluşturma türü ve JavaScript VM örneği.

Bellek paneli, anlık görüntüyü yükleyip ayrıştırdığında YÜĞÜN ANLIK GÖRÜNTÜLERİ bölümündeki anlık görüntü başlığının altında erişilebilir JavaScript nesnelerinin toplam boyutunu gösterir.

Erişilebilen nesnelerin toplam boyutu.

Anlık görüntüler, bellek grafiğindeki yalnızca genel nesneden erişilebilen nesneleri gösterir. Anlık görüntü alma işlemi her zaman çöp toplamayla başlar.

görürsünüz.

Dağınık Item nesnelerinin yığın anlık görüntüsü.

Anlık görüntüleri temizleme

Tüm anlık görüntüleri kaldırmak için Tüm profilleri temizle'yi tıklayın:

Tüm profilleri temizleyin.

Anlık görüntüleri görüntüle

Farklı amaçlarla anlık görüntüleri farklı perspektiflerden incelemek için üstteki açılır menüden görünümlerden birini seçin:

Göster İçerik Amaç
Özet Oluşturucu adlarına göre gruplandırılmış nesneler. Nesneleri ve türlerine göre bellek kullanımlarını bulmak için kullanın. DOM sızıntılarını izleme için yararlıdır.
Karşılaştırma İki anlık görüntü arasındaki farklar. Bir işlemden önce ve sonra iki (veya daha fazla) anlık görüntüyü karşılaştırmak için kullanın. Boşaltılan bellek ve referans sayısında delta değerini inceleyerek bellek sızıntısının varlığını ve nedenini onaylayın.
Kısıtlama Yığın içeriği Nesne yapısının daha iyi bir görünümünü sağlar ve küresel ad alanında (pencere) referans verilen nesneleri analiz ederek bu nesnelerin neden var olduğunu bulmaya yardımcı olur. Kapsamı analiz etmek ve nesnelerinizi düşük düzeyde incelemek için kullanın.
İstatistikler Bellek ayırma pasta grafiği Kod, dize, JS dizileri, yazılmış diziler ve sistem nesnelerine ayrılan bellek bölümlerinin göreceli boyutlarını görebilirsiniz.

Üstteki açılır menüden seçilen özet görünümü.

Özet görünümü

Başlangıçta, Özet görünümünde bir sütunda yapıcıları listeleyen bir yığın anlık görüntüsü açılır. Oluşturdukları nesneleri görmek için kurucuları genişletebilirsiniz.

Genişletilmiş bir kurucu içeren özet görünümü.

Alakasız kurucuları filtrelemek için Özet görünümünün üst kısmındaki Sınıf filtresi'ne incelemek istediğiniz bir ad yazın.

Oluşturucu adlarının yanındaki sayılar, oluşturucuyla oluşturulan toplam nesne sayısını gösterir. Özet görünümünde aşağıdaki sütunlar da gösterilir:

  • Mesafe, düğümlerin en kısa basit yolunu kullanarak köke olan mesafeyi gösterir.
  • Sığ boyut, belirli bir kurucu tarafından oluşturulan tüm nesnelerin sığ boyutlarının toplamını gösterir. Sığ boyut, bir nesnenin kendisi tarafından tutulan bellek boyutudur. Genellikle diziler ve dizelerin boyutu daha büyüktür. Nesne boyutları konusuna da göz atın.
  • Saklanılan boyut, aynı nesne grubu arasında saklanan maksimum boyutu gösterir. Saklanan boyut, bir nesneyi silerek ve bağımlılarını artık erişilemez hale getirerek boşalttığınız bellek boyutudur. Nesne boyutları konusuna da göz atın.

Bir kurucuyu genişlettiğinizde Özet görünümünde tüm örnekleri gösterilir. Her örnek, ilgili sütunlarda sığ ve tutulan boyutlarının dökümünü alır. @ karakterinden sonraki sayı, nesnenin benzersiz kimliğidir. Yığın anlık görüntülerini nesne bazında karşılaştırmanıza olanak tanır.

Oluşturucu filtreleri

Özet görünümü, kurucuları verimsiz bellek kullanımının yaygın örneklerine göre filtrelemenize olanak tanır.

Bu filtreleri kullanmak için işlem çubuğundaki en sağdaki açılır menüden aşağıdaki seçeneklerden birini belirleyin:

  • Tüm nesneler: Geçerli anlık görüntü tarafından yakalanan tüm nesneler. Varsayılan olarak ayarlanır.
  • 1. anlık görüntüden önce ayrılmış nesneler: İlk anlık görüntü alınmadan önce oluşturulan ve bellekte kalan nesneler.
  • 1. anlık görüntü ile 2. anlık görüntü arasında ayrılan nesneler: En son anlık görüntü ile önceki anlık görüntü arasındaki nesne farkını görüntüleyin. Her yeni anlık görüntü, açılır listeye bu filtrenin bir artışını ekler.
  • Yinelenen dizeler: Bellekte birden çok kez depolanmış dize değerleri.
  • Ayrılmış düğümler tarafından saklanan nesneler: Ayrılmış bir DOM düğümü tarafından referans verildiği için etkin durumda tutulan nesneler.
  • Geliştirici Araçları Konsolu tarafından saklanan nesneler: Geliştirici Araçları Konsolu aracılığıyla değerlendirildikleri veya bunlarla etkileşim kuruldukları için bellekte tutulan nesneler.

Özet bölümündeki özel girişler

Özet görünümü, oluşturuculara göre gruplandırmaya ek olarak nesneleri aşağıdakilere göre de gruplandırır:

  • Array veya Object gibi yerleşik işlevler.
  • Etiketlerine göre gruplandırılmış HTML öğeleri (ör. <div>, <a>, <img> ve diğerleri).
  • Kodunuzda tanımladığınız işlevler.
  • Oluşturuculara dayalı olmayan özel kategoriler.

Oluşturucu girişleri.

(array)

Bu kategori, JavaScript'te görünen nesnelere doğrudan karşılık gelmeyen çeşitli dahili dizi benzeri nesneleri içerir.

Örneğin, JavaScript Array nesnelerinin içeriği, yeniden boyutlandırmayı kolaylaştırmak için (object elements)[] adlı ikincil bir dahili nesnede depolanır. Benzer şekilde, JavaScript nesnelerindeki adlandırılmış özellikler genellikle (array) kategorisinde de listelenen (object properties)[] adlı ikincil dahili nesnelerde depolanır.

(compiled code)

Bu kategori, JavaScript veya WebAssembly tarafından tanımlanan işlevleri çalıştırabilmek için V8'in ihtiyaç duyduğu dahili verileri içerir. Her işlev, küçük ve yavaştan büyük ve hızlıya kadar çeşitli şekillerde temsil edilebilir.

V8, bu kategorideki bellek kullanımını otomatik olarak yönetir. Bir işlev çok kez çalıştırılırsa V8, daha hızlı çalışabilmesi için işlev için daha fazla bellek kullanır. Bir işlev uzun süredir çalışmıyorsa V8, ilgili işlevin dahili verilerini temizleyebilir.

(concatenated string)

V8, JavaScript + operatörüyle olduğu gibi iki dizeyi birleştirdiğinde sonucu dahili olarak Rope veri yapısı olarak da bilinen "birleştirilmiş dize" olarak temsil etmeyi seçebilir.

V8, iki kaynak dizenin tüm karakterlerini yeni bir dizeye kopyalamak yerine, iki kaynak dizeyi işaret eden first ve second adlı dahili alanlara sahip küçük bir nesne ayırır. Bu sayede V8 zaman ve bellek tasarrufu sağlar. JavaScript kodu açısından bunlar normal dizelerdir ve diğer dizelerle aynı şekilde çalışırlar.

InternalNode

Bu kategori, V8 dışında ayrılmış nesneleri (ör. Blink tarafından tanımlanan C++ nesneleri) temsil eder.

C++ sınıf adlarını görmek için Test için Chrome'u kullanın ve aşağıdakileri yapın:

  1. Geliştirici Araçları'nı açın ve Ayarlar > Deneysel > Yığın anlık görüntülerinde dahili öğeleri gösterme seçeneğini göster'i etkinleştirin.
  2. Bellek panelini açın, Toplu hafıza anlık görüntüsü'nü seçin ve Dahili verileri açığa çıkar (Uygulamaya özel ek ayrıntıları içerir) seçeneğini etkinleştirin.
  3. InternalNode'ün çok fazla bellek tutmasına neden olan sorunu yeniden oluşturun.
  4. Yığın anlık görüntüsü alın. Bu anlık görüntüde, nesneler InternalNode yerine C++ sınıf adlarına sahiptir.
(object shape)

V8'de Hızlı Özellikler bölümünde açıklandığı gibi, V8 aynı özelliklere ve aynı sıraya sahip birden fazla nesnenin verimli bir şekilde temsil edilebilmesi için gizli sınıfları (veya şekillerini) izler. Bu kategori, system / Map (JavaScript Map ile ilgili değildir) adlı gizli sınıfları ve ilgili verileri içerir.

(sliced string)

V8'in bir alt dize alması gerektiğinde (ör. JavaScript kodu String.prototype.substring()'ı çağırdığında) V8, orijinal dizeden ilgili tüm karakterleri kopyalamak yerine bir dilimlenmiş dize nesnesi ayırmayı seçebilir. Bu yeni nesne, orijinal dizeye işaret eden bir işaretçi içerir ve orijinal dizede hangi karakter aralığının kullanılacağını tanımlar.

JavaScript kodu açısından bunlar normal dizelerdir ve diğer dizelerle aynı şekilde çalışırlar. Dilimlenmiş bir dize çok fazla bellek tutuyorsa program 2869 numaralı sorunu tetiklemiş olabilir ve dilimlenmiş dizeyi "düzleştirmek" için bilinçli adımlar atmaktan fayda görebilirsiniz.

system / Context

system / Context türündeki dahili nesneler, iç içe yerleştirilmiş bir işlevin erişebileceği bir JavaScript kapsamı olan kapanış içindeki yerel değişkenleri içerir.

Her işlev örneği, bu değişkenlere erişebilmek için yürütüldüğü Context'ye giden dahili bir işaretçi içerir. Context nesneleri JavaScript'ten doğrudan görünmese de bunlar üzerinde doğrudan kontrol sahibisiniz.

(system)

Bu kategori, henüz daha anlamlı bir şekilde sınıflandırılmamış çeşitli dahili nesneleri içerir.

Karşılaştırma görünümü

Karşılaştırma görünümü, birden fazla anlık görüntüyü birbiriyle karşılaştırarak sızdırılmış nesneleri bulmanızı sağlar. Örneğin, bir işlemi yapıp geri alma (ör. bir dokümanı açıp kapatma) işlemi, geride ek nesneler bırakmamalıdır.

Belirli bir işlemin sızıntı oluşturmadığını doğrulamak için:

  1. İşlem gerçekleştirmeden önce yığın anlık görüntüsü alın.
  2. Bir işlem gerçekleştirin. Yani, bir sayfayla veri sızıntısına neden olabileceğini düşündüğünüz bir şekilde etkileşim kurun.
  3. Ters işlem gerçekleştirin. Yani, tam tersini yapın ve bunu birkaç kez tekrarlayın.
  4. İkinci bir yığın fotoğrafı çekin ve görünümünü Karşılaştırma olarak değiştirerek 1. Fotoğraf ile karşılaştırın.

Karşılaştırma görünümü, iki anlık görüntü arasındaki farkı gösterir. Bir toplam girişi genişletildiğinde eklenen ve silinen nesne örnekleri gösterilir:

1. anlık görüntüyle karşılaştırma.

Kapsama görünümü

Kapsayıcılık görünümü, uygulamanızın nesne yapısının "kuş bakışı görünümüdür". Bu özellik, işlev kapatmalarının içine göz atmanıza, JavaScript nesnelerinizi oluşturan VM dahili nesnelerini gözlemlemenize ve uygulamanızın ne kadar bellek kullandığını çok düşük bir düzeyde anlamanıza olanak tanır.

Bu görünümde birkaç giriş noktası bulunur:

  • DOMWindow nesneleri. JavaScript kodu için genel nesneler.
  • GC kökleri. Sanal makinenin çöp toplayıcısı tarafından kullanılan GC kökleri. GC kökleri, yerleşik nesne haritalarından, simge tablolarından, sanal makine iş parçacığı yığınlarından, derleme önbelleklerinden, tutamak kapsamlarından ve genel tutamaklardan oluşabilir.
  • Yerel nesneler. DOM düğümleri ve CSS kuralları gibi otomasyona izin vermek için JavaScript sanal makinesine "itilen" tarayıcı nesneleri.

Kapsamı görüntüleme.

Sabitleyiciler bölümü

Anı panelinin alt kısmındaki Saklama bölümünde, görünümde seçilen nesneyi işaret eden nesneler gösterilir. İstatistikler hariç görünümlerden herhangi birinde farklı bir nesne seçtiğinizde Hafıza paneli Sadık Kullanıcılar bölümünü günceller.

Sabitleyiciler bölümü.

Bu örnekte, seçilen dize bir Item örneğinin x özelliği tarafından saklanır.

Tutucuları yoksayma

Diğer nesnelerin seçili nesneyi tutup tutmadığını öğrenmek için tutucuları gizleyebilirsiniz. Bu seçenekle, önce bu tutucuyu koddan kaldırmanız ve ardından yığın anlık görüntüsünü yeniden almanız gerekmez.

Açılır menüdeki &quot;Bu hizmet sözleşmesini yoksay&quot; seçeneği.

Bir koruyucuyu gizlemek için sağ tıklayın ve Bu koruyucuyu yoksay'ı seçin. Yoksayılan hizmet sözleşmeleri, Mesafe sütununda ignored olarak işaretlenir. Tüm takipçilerin yoksayılmasını durdurmak için üstteki işlem çubuğunda Yoksayılan takipçileri geri yükle'yi tıklayın.

Belirli bir nesneyi bulma

Toplanan yığınta bir nesneyi bulmak için Ctrl + F tuşlarını kullanarak arama yapabilir ve nesne kimliğini girebilirsiniz.

Kapsamı kapatan işlevleri ayırt etmek için işlevlere ad verme

Anlık görüntüdeki kapanışları ayırt edebilmeniz için işlevlere ad vermeniz çok faydalıdır.

Örneğin, aşağıdaki kodda adlandırılmış işlevler kullanılmamıştır:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function() { // this is NOT a named function
    return largeStr;
  };

  return lC;
}

Bu örnekte ise:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function lC() { // this IS a named function
    return largeStr;
  };

  return lC;
}

Kapsamı içinde adlandırılmış işlev.

DOM sızıntılarını tespit etme

Yığın profili, tarayıcıya özgü nesneler (DOM düğümleri ve CSS kuralları) ile JavaScript nesneleri arasındaki iki yönlü bağımlılıkları yansıtabilir. Bu, unutulmuş ve ayrılmış DOM alt ağaçları nedeniyle ortaya çıkan ve görünmeyen sızıntıların keşfedilmesine yardımcı olur.

DOM sızıntıları düşündüğünüzden daha büyük olabilir. Aşağıdaki örneği inceleyin. #tree çöpleri ne zaman toplanır?

  var select = document.querySelector;
  var treeRef = select("#tree");
  var leafRef = select("#leaf");
  var body = select("body");

  body.removeChild(treeRef);

  //#tree can't be GC yet due to treeRef
  treeRef = null;

  //#tree can't be GC yet due to indirect
  //reference from leafRef

  leafRef = null;
  //#NOW #tree can be garbage collected

#leaf, üst öğesine (parentNode) ve yinelemeli olarak #tree'e kadar referans tutar. Bu nedenle, yalnızca leafRef'ın değeri null olduğunda #tree altındaki tüm ağaç GC için aday olur.

DOM alt ağaçları