Bellek terminolojisi

Meggin Kearney
Meggin Kearney

Bu bölümde bellek analizinde kullanılan yaygın terimler açıklanmakta ve farklı dillerdeki çeşitli bellek profili oluşturma araçları için geçerlidir.

Burada açıklanan terimler ve kavramlar, Chrome Geliştirici Araçları Yığın Profil Aracı'yla ilgilidir. Java, .NET veya başka bir bellek profil aracı ile çalıştıysanız bilgilerinizi tazeleyebilirsiniz.

Nesne boyutları

Hafızayı, basit türleri (sayılar ve dizeler gibi) ve nesneleri (ilişkisel diziler) içeren bir grafik olarak düşünebilirsiniz. Bir dizi birbirine bağlı nokta içeren bir grafik aşağıdaki gibi görsel olarak gösterilebilir:

Hafızanın görsel temsili

Bir nesne belleği iki şekilde saklayabilir:

  • Doğrudan nesnenin kendisi tarafından.
  • Diğer nesnelere referansları tutarak ve dolayısıyla bu nesnelerin bir çöp toplayıcı (kısaca GC) tarafından otomatik olarak imha edilmesini önleyerek örtülü bir şekilde.

Geliştirici Araçları'nda ("Profiller" altında bulunan bellek sorunlarını incelemeye yönelik bir araç) Yığın Profil Aracı ile çalışırken muhtemelen birkaç farklı bilgi sütununa bakarsınız. Göze çarpan iki boyut, Sığ Boyut ve Tutulan Boyut'tur, peki bunlar neyi temsil eder?

Derinlikli ve Korunan Boyut

Sığ boyut

Bu, nesnenin kendisinin tuttuğu belleğin boyutudur.

Tipik JavaScript nesnelerinin, açıklamaları ve anlık değerleri depolamak için ayrılmış bir belleği vardır. Genellikle yalnızca diziler ve dizeler kayda değer düzeyde yüzeysel boyuta sahip olabilir. Bununla birlikte, dizeler ve harici dizilerin ana depolama alanları genellikle oluşturucu belleğinde bulunur. Bu da JavaScript yığınında yalnızca küçük bir sarmalayıcı nesnesinin ortaya çıkmasına neden olur.

Oluşturucu belleği, denetlenen bir sayfanın oluşturulduğu sürecin tüm belleğidir: yerel bellek + sayfanın JS yığın belleği + sayfa tarafından başlatılan tüm özel çalışanların JS yığın belleği. Bununla birlikte, küçük bir nesne bile otomatik atık toplama işlemiyle diğer nesnelerin yok edilmesini önleyerek, dolaylı olarak büyük miktarda bellek barındırabilir.

Tutulan boyut

Bu, nesnenin kendisi ve GC köklerinden erişilemeyen bağımlı nesneleri silindikten sonra serbest bırakılan bellek boyutunu belirtir.

GC kökleri, yerel koddan V8 dışındaki bir JavaScript nesnesine referans verilirken oluşturulan (yerel veya global) herkese açık kullanıcı adlarından oluşur. Bu tür herkese açık kullanıcı adlarının tümü, GC kökleri > Kimlik kapsamı ve GC kökleri > Genel işleyiciler altındaki bir yığın anlık görüntüsünde bulunabilir. Bu dokümandaki herkese açık kullanıcı adlarını, tarayıcı uygulamasının ayrıntılarına girmeden açıklamak kafa karıştırıcı olabilir. Hem GC kökleri hem de tutma yerleriyle ilgili endişelenmeniz gerekmez.

Kullanıcıların ilgisini çekmeyen birçok dahili GC kökü bulunmaktadır. Uygulama açısından bakıldığında, kökler aşağıdaki gibidir:

  • Pencere global nesnesi (her bir iframe'de). Yığın anlık görüntülerinde bir uzaklık alanı bulunur. Bu alan, pencereden gelen en kısa tutma yolundaki özellik referanslarının sayısıdır.
  • Dokümandan geçerek erişilebilen tüm yerel DOM düğümlerini içeren doküman DOM ağacı. Bunların hepsinde JS sarmalayıcıları olmayabilir ancak sarmalayıcıları varsa belge yayında kalırken sarmalayıcılar etkin olacaktır.
  • Bazen nesneler hata ayıklayıcı bağlamı ve Geliştirici Araçları konsolu tarafından saklanabilir (ör. konsol değerlendirmesinden sonra). Temiz konsola sahip ve hata ayıklayıcıda etkin kesme noktası bulunmayan yığın anlık görüntüleri oluşturun.

Bellek grafiği bir kökle başlar. Bu, tarayıcının window nesnesi veya Node.js modülünün Global nesnesi olabilir. Bu kök nesnenin GC'nin nasıl olduğunu kontrol etmezsiniz.

Kök nesne kontrol edilemiyor

Kökten erişilemeyen her öğe GC'yi alır.

Ağaç tutan nesneler

Yığın, birbirine bağlı nesnelerden oluşan bir ağdır. Matematikte bu yapıya grafik veya bellek grafiği denir. Grafik, her ikisine de etiket verilen kenarlar aracılığıyla bağlanan düğümlerden oluşturulur.

  • Düğümler (veya nesneler), bunları oluşturmak için kullanılan kurucu işlevinin adı kullanılarak etiketlenir.
  • Edge'lar, özelliklerin adları kullanılarak etiketlenir.

Yığın Profil Aracı'nı kullanarak nasıl profil kaydedeceğinizi öğrenin. Aşağıdaki Yığın Profil Aracı kaydında görebileceğimiz göz alıcı şeylerden bazıları mesafe, yani GC kökünden uzaklık. Aynı türdeki hemen hemen tüm nesneler aynı mesafede, ancak birkaç nesne de daha büyük bir uzaklıktaysa bu durumu araştırmaya değer.

Kökten uzaklık

Dominatörler

Her nesnenin tam olarak bir hakimi olduğu için baskın nesneler ağaç yapısından oluşur. Bir nesnenin hakimi, hakim olduğu bir nesneye doğrudan referans içermeyebilir. Yani, hakimin ağacı, grafiğin yayılan bir ağacı değildir.

Aşağıdaki diyagramda:

  • 1. düğüm, 2. düğüme baskındır
  • 2. düğüm, 3., 4. ve 6. düğüme baskındır
  • 3. düğüm, 5. düğüme baskındır
  • 5. düğüm, 8. düğüme baskındır
  • 6. düğüm, 7. düğüme baskındır

Dominator ağaç yapısı

Aşağıdaki örnekte #3 düğümü #10 öğesinin baskın öğesidir ancak #7, GC'den #10'ye kadar her basit yolda da mevcuttur. Bu nedenle, kökten A'ya kadar her basit yolda B nesnesi varsa A nesnesinin baskınlayıcısı B nesnesidir.

Animasyonlu dominator çizimi

V8 özellikleri

Hafıza profili oluştururken yığın anlık görüntülerinin neden belirli bir şekilde göründüğünü anlamak faydalıdır. Bu bölümde, özellikle V8 JavaScript sanal makinesi (V8 sanal makinesi veya sanal makinesi) ile ilgili bellekle ilgili bazı konular açıklanmaktadır.

JavaScript nesne gösterimi

Üç temel tür vardır:

  • Sayılar (ör. 3,14159..)
  • Boole değerleri (doğru veya yanlış)
  • Dizeler (ör. "Werner Heisenberg")

Diğer değerlere referansta bulunamazlar ve her zaman yaprak veya sonlandıran düğümlerdirler.

Numaralar şu şekilde depolanabilir:

  • küçük tam sayılar (SMI'lar) olarak adlandırılan doğrudan 31 bitlik tam sayı değerleri veya
  • yığın numaraları olarak adlandırılan yığın nesneleri. Yığın numaraları, SMI formuna uymayan değerleri (ör. çift değerler) depolamak için veya bir değerin kutulanması gerektiğinde (ör. özellik ayarlama) kullanılır.

Dizeler şunlardan birinde depolanabilir:

  • Sanal makine yığını veya
  • oluşturucunun belleğinde harici olarak olmasını sağlar. Sarmalayıcı nesne, örneğin komut dosyası kaynaklarının ve web'den alınan diğer içeriklerin sanal makine yığınına kopyalanmak yerine depolandığı harici depolamaya erişmek için oluşturulur ve kullanılır.

Yeni JavaScript nesneleri için bellek, özel bir JavaScript yığınından (veya sanal makine yığınından) ayrılır. Bu nesneler, V8'in çöp toplayıcısı tarafından yönetilir. Bu nedenle, bunlara en az bir güçlü referans olduğu sürece hayatta kalırlar.

Yerel nesneler, JavaScript yığınında olmayan diğer her şeydir. Yığın nesnesinin aksine yerel nesne, V8 çöp toplayıcı tarafından kullanım ömrü boyunca yönetilmez ve yalnızca JavaScript sarmalayıcı nesnesi kullanılarak JavaScript'ten erişilebilir.

Eksileri dizesi, depolanıp birleştirilen dize çiftlerinden oluşan bir nesnedir ve birleştirme işlemi sonucunda ortaya çıkar. cons dizesi içerikleri yalnızca gerektiğinde birleştirilir. Birleştirilmiş bir dizenin alt dizesinin oluşturulması gerektiğinde buna örnek olarak verilebilir.

Örneğin, a ve b değerlerini birbirine bağlarsanız birleştirme işleminin sonucunu temsil eden bir dize (a, b) elde edersiniz. d'yi daha sonra bu sonuçla birleştirdiyseniz başka bir eksi dizesi ((a, b), d) alırsınız.

Diziler: Dizi, sayısal tuşlara sahip bir nesnedir. Bunlar, V8 sanal makinesinde büyük miktarlarda veri depolamak için yaygın olarak kullanılır. Sözlük gibi kullanılan anahtar/değer çifti kümeleri dizilerle yedeklenir.

Tipik bir JavaScript nesnesi, depolamak için kullanılan iki dizi türünden biri olabilir:

  • ve
  • sayısal öğeler

Çok az sayıda özelliğin olduğu durumlarda, bunlar JavaScript nesnesinin kendisinde dahili olarak depolanabilir.

Harita: Nesnenin türünü ve düzenini açıklayan bir nesnedir. Örneğin haritalar, hızlı mülk erişimi için örtülü nesne hiyerarşilerini tanımlamak amacıyla kullanılır.

Nesne grupları

Her yerel nesne grubu, birbirine karşılıklı referanslar içeren nesnelerden oluşur. Örneğin, her düğümün üst düğüme ve bir sonraki alt ve sonraki kardeşe bağlantı verdiği ve böylece bağlı bir grafik oluşturduğu bir DOM alt ağacını düşünün. Yerel nesnelerin JavaScript yığınında temsil edilmediğini, bu nedenle sıfır boyutlarının olduğunu unutmayın. Bunun yerine sarmalayıcı nesneler oluşturulur.

Her sarmalayıcı nesne, komutları yönlendirmek için karşılık gelen yerel nesneye bir referans içerir. Kendi sırasına göre bir nesne grubu sarmalayıcı nesneleri içerir. Ancak GC, sarmalayıcıları artık referans verilmeyen nesne gruplarını serbest bırakacak kadar akıllı olduğundan bu işlem, toplanamayan bir döngü oluşturmaz. Ancak tek bir sarmalayıcı serbest bırakmayı unutulduğunda tüm grup ve ilişkili sarmalayıcılar tutulur.