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:
- Profil oluşturmak istediğiniz bir sayfada Geliştirici Araçları'nı açın ve Bellek paneline gidin.
- 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.
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.
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.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: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. |
Ö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.
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
veyaObject
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.
(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:
- 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.
- 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.
InternalNode
'ün çok fazla bellek tutmasına neden olan sorunu yeniden oluşturun.- 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:
- İşlem gerçekleştirmeden önce yığın anlık görüntüsü alın.
- 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.
- Ters işlem gerçekleştirin. Yani, tam tersini yapın ve bunu birkaç kez tekrarlayın.
- İ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:
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.
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.
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.
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;
}
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.