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 oluşturucu, sayfanızın 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ÜK ANIK 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 öğe 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 Yapıcı adlarına göre gruplandırılan 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çerikleri Nesne yapısının daha iyi bir görünümünü sağlar ve küresel ad alanında (pencere) referans verilen nesnelerin neden var olduğunu bulmak için bu nesnelerin analiz edilmesine yardımcı olur. Kapanışları analiz etmek ve nesneleri ayrıntılı bir şekilde incelemek için kullanabilirsiniz.
İstatistikler Bellek ayırmanın 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, Oluşturucular'ın bir sütunda listelendiği bir yığın anlık görüntüsü açılır. Oluşturucuları örneklendirdikleri nesneleri görmek için genişletebilirsiniz.

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

Alakasız oluşturucuları 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 dizeler daha büyük sığ boyutlara sahiptir. Nesne boyutları konusuna da göz atın.
  • Saklanılan boyut, aynı nesne grubu arasında saklanan maksimum boyutu gösterir. Tutulan boyut, bir nesneyi silerek ve bağımlılarını artık erişilemez hale getirerek serbest bırakabileceğiniz 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 başına 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 parçasını ekler.
  • Yinelenen dizeler: Bellekte birden çok kez depolanmış dize değerleri.
  • Ayrılan düğümler tarafından tutulan nesneler: Ayrı bir DOM düğümüne referans verdiği için aktif kalan 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ü, kuruculara 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 bir süredir çalışmamışsa V8, bu işlevin dahili verilerini temizleyebilir.

(concatenated string)

V8 iki dizeyi birleştirdiğinde (ör. JavaScript + operatöründe), sonucu dahili olarak "birleştirilmiş dize" olarak (Rope veri yapısı olarak da bilinir) temsil edebilir.

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 kategoride, system / Map adlı gizli sınıflar (Map JavaScript ile ilgili olmayan) ve ilgili veriler yer alır.

(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 dizeler gibi davranı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 close içindeki yerel değişkenleri içerir.

Her işlev örneği, yürütüldüğü Context'ye giden dahili bir işaretçi içerir. Böylece bu değişkenlere erişebilir. 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ılan nesneleri bulmanıza olanak tanır. Örneğin, bir işlem yapıp bunu tersine çevirmek (örneğin, bir belgeyi açıp kapatmak) geride fazladan nesne 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". İşlev kapanışlarına göz atmanızı, JavaScript nesnelerinizi oluşturan sanal makine dahili nesnelerini gözlemlemenizi ve uygulamanızın çok düşük bir düzeyde ne kadar bellek kullandığını 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 eşlemeleri, simge tabloları, sanal makine iş parçacığı yığınları, derleme önbellekleri, herkese açık kullanıcı adı kapsamları ve genel herkese açık kullanıcı adlarından 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ü

Hafıza 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 Anı 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 tuttuğunu öğ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 tutucuyu gizlemek için sağ tıklayın ve Bu tutucuyu yoksay'ı seçin. Yoksayılan hizmet sözleşmeleri, Mesafe sütununda ignored olarak işaretlenir. Tüm takipçileri yoksaymayı 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şlevleri adlandırma

Anlık görüntüdeki kapatmaları 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'ye 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ı