WinUI uygulamalarında çöp toplama performansını geliştirme

Windows Uygulama SDK'sı ile oluşturulan ve C# dilinde yazılan WinUI uygulamaları.NET çöp toplayıcısından otomatik bellek yönetimi alır. Bu makalede, WinUI uygulamalarında .NET çöp toplayıcısı için davranış ve performans en iyi yöntemleri özetlemektedir. .NET çöp toplayıcısının nasıl çalıştığı hakkında daha fazla bilgi ve çöp toplayıcı performansının hatalarını ayıklamaya ve çözümlemeye yönelik araçlar için bkz . Çöp toplama.

Uyarı

Atık toplayıcının varsayılan davranışına müdahale etmek, uygulamanızla ilgili genel bellek sorunlarını kesinlikle gösterir. Visual Studio'daki Bellek Kullanımı aracını ve çöp toplama ve performans yönergelerini kullanarak koleksiyonlarda kalan nesneleri belirleyin.

Çöp toplayıcı, yönetilen yığının bellek tüketimini çöp toplamanın yapması gereken iş miktarıyla dengeleyerek ne zaman çalıştıracağını belirler. Çöp toplayıcının bunu yapmanın yollarından biri, yığını nesillere bölmek ve yığının yalnızca bir kısmını çoğu zaman toplamaktır. Yönetilen yığında üç nesil vardır:

  • Nesil 0 Bu nesil, 85 KB veya daha büyük olmadığı sürece yeni ayrılan nesneler içerir ve bu durumda büyük nesne yığınının bir parçası olurlar. Büyük nesne yığını 2. nesil koleksiyonlarla toplanır. 0. nesil koleksiyonlar, en sık oluşan koleksiyon türüdür ve yerel değişkenler gibi kısa ömürlü nesneleri temizler.
  • 1. Nesil Bu nesil, 0. nesil koleksiyonlarda hayatta kalmış nesneler içerir. 0. nesil ile 2. nesil arasında arabellek görevi görür. 1. nesil koleksiyonlar, nesil 0 koleksiyonlarından daha az sıklıkta gerçekleşir ve önceki nesil 0 koleksiyonları sırasında etkin olan geçici nesneleri temizler. 1. nesil koleksiyon, 0. nesli de toplar.
  • 2. Nesil Bu nesil, 0. nesil ve 1. nesil koleksiyonlarda hayatta kalmış uzun ömürlü nesneler içerir. 2. nesil koleksiyonlar en az sıklıkta olan koleksiyonlardır ve 85 KB veya daha büyük nesneler içeren büyük nesne yığını da dahil olmak üzere yönetilen yığının tamamını toplar.

Çöp toplayıcının performansını iki açıdan ölçebilirsiniz: çöp toplama işlemi için geçen süre ve yönetilen yığının bellek tüketimi. Yığın boyutu 100 MB'ın altında olan küçük bir uygulamanız varsa bellek tüketimini azaltmaya odaklanın. Yönetilen yığını 100 MB'tan büyük bir uygulamanız varsa yalnızca çöp toplama süresini azaltmaya odaklanın. .NET çöp toplayıcısının daha iyi performans elde etmelerine şu şekilde yardımcı olabilirsiniz.

Bellek tüketimini azaltma

Yayın referansları

Uygulamanızdaki bir nesneye başvuru, bu nesnenin ve başvurduğunu tüm nesnelerin toplanmasını engeller. .NET derleyicisi, bir değişkenin artık kullanılmadığını algılamak için iyi bir iş yapar, bu nedenle bu değişken tarafından tutulan nesneler koleksiyon için uygun olur. Ancak bazı durumlarda, nesne grafiğinin bir bölümü uygulamanızın kullandığı kitaplıklara ait olabileceğinden bazı nesnelerin diğer nesnelere başvurusu olduğu açıkça belli olmayabilir. Bir çöp toplama işleminde hangi nesnelerin hayatta kaldığını bulmaya yönelik araçlar ve teknikler hakkında bilgi edinmek için bkz . Çöp toplama ve performans.

Yararlıysa çöp toplamaya neden olur

Bir çöp toplama işlemini yalnızca uygulamanızın performansını ölçtükten ve bir toplama işleminin performansını artıracağını belirledikten sonra oluşturun.

GC çağırarak bir neslin çöp toplama işlemini oluşturabilirsiniz . Toplama(n); burada n , toplamak istediğiniz nesildir (0, 1 veya 2).

Uyarı

Atık toplayıcı bir toplama işlemini gerçekleştirmek için en iyi zamanı belirlemek için birçok buluşsal yöntem kullandığından ve çoğu durumda cpu'nun gereksiz bir şekilde kullanılması gerektiğinden, uygulamanızda çöp toplamayı zorlamamanızı öneririz. Ancak, uygulamanızda artık kullanılmayan çok sayıda nesneniz olduğunu biliyorsanız ve bu belleği sisteme döndürmek istiyorsanız, çöp toplamayı zorlamak uygun olabilir. Örneğin, oyun başlamadan önce bellek boşaltmak için bir oyundaki yükleme dizisinin sonunda bir koleksiyon oluşturabilirsiniz.   Yanlışlıkla çok fazla çöp toplama işlemini önlemek için GCCollectionMode'yiİyileştirilmiş olarak ayarlayabilirsiniz. Bu, atık toplayıcıya yalnızca koleksiyonun gerekçelendirilecek kadar üretken olacağını belirlerse bir toplama başlatmasını ister.

Çöp toplama süresini azaltma

Bu bölüm, uygulamanızı analiz edip büyük çöp toplama sürelerini gözlemlediyseniz geçerlidir. Çöp toplamayla ilgili duraklatma süreleri, tek bir çöp toplama geçişini çalıştırmak için geçen süreyi ve uygulamanızın çöp toplama işlemleri için harcadığı toplam süreyi içerir. Koleksiyon yapmak için gereken süre, toplayıcının analiz etmek zorunda olduğu canlı veri miktarına bağlıdır. 0. nesil ve 1. nesil boyut sınırına sahip ancak uygulamanızda daha uzun ömürlü nesneler etkin olduğundan 2. nesil büyümeye devam ediyor. Bu, 0. nesil ve 1. nesil için koleksiyon sürelerinin sınırlandığı, 2. nesil koleksiyonların ise daha uzun sürebileceği anlamına gelir. Çöp toplama işleminin ne sıklıkta yapıldığı, genellikle ne kadar bellek ayırdığınıza bağlıdır çünkü çöp toplama, ayırma isteklerini karşılayabilmek için belleği boşaltır.

Çöp toplayıcı, iş yapmak için uygulamanızı ara sıra duraklatır, ancak toplama işlemi boyunca uygulamanızı duraklatması gerekmez. Duraklatma süreleri, özellikle 0. nesil ve 1. nesil koleksiyonlar için uygulamanızda genellikle kullanıcı tarafından algılanamaz. .NET çöp toplayıcısının Arka plan çöp toplama özelliği, uygulamanız çalışırken 2. nesil koleksiyonların eşzamanlı olarak gerçekleştirilmesini sağlar ve uygulamanızı yalnızca kısa bir süre duraklatır. Ancak 2. nesil bir koleksiyonu arka plan koleksiyonu olarak yapmak her zaman mümkün değildir. Bu durumda, yeterince büyük bir yığınınız varsa (100 MB'tan fazla), kullanıcı tarafından algılanabilir bir duraklatma meydana gelebilir.

Sık çöp toplama işlemleri, uygulamanızda cpu artışına, güç tüketiminin artmasına, daha uzun yükleme sürelerine veya kare hızlarının azalmasına katkıda bulunabilir. Aşağıda, yönetilen WinUI uygulamanızda çöp toplama süresini ve toplamayla ilgili duraklamaları azaltmak için kullanabileceğiniz bazı teknikler verilmiştir.

Bellek ayırmalarını azaltma

Herhangi bir nesne ayırmazsanız, sistemde yetersiz bellek koşulu olmadığı sürece çöp toplayıcı çalışmaz. Doğrudan ayırdığınız bellek miktarını azaltmak, daha az sıklıktaki çöp toplama işlemlerine dönüşür.

Uygulamanızın bazı bölümlerinde duraklamalar tamamen istenmeyen bir durumsa, daha az performans açısından kritik bir süre boyunca gerekli nesneleri önceden ayırabilirsiniz. Örneğin, bir oyun, bir düzeyin yükleme ekranı sırasında oyun için gereken tüm nesneleri ayırabilir ve oyun sırasında herhangi bir ayırma yapmayabilir. Bu, kullanıcı oyunu oynarken duraklamaları önler ve daha yüksek ve daha tutarlı bir kare hızına neden olabilir.

Orta uzunlukta yaşam süresine sahip nesnelerden kaçınarak 2. nesil koleksiyonları azaltın

Jenerasyon çöp toplamaları, uygulamanızda gerçekten kısa ömürlü ve/veya gerçekten uzun ömürlü nesneler olduğunda en iyi performansı gösterir. Kısa ömürlü nesneler daha ucuz nesil 0 ve 1. nesil koleksiyonlarda toplanır ve uzun ömürlü nesneler seyrek toplanan 2. nesil olarak yükseltilir. Uzun ömürlü nesneler, uygulamanızın süresi boyunca veya belirli bir sayfa veya oyun düzeyi gibi uygulamanızın önemli bir döneminde kullanılan nesnelerdir.

Geçici ömrü olan ancak 2. nesile yükseltilecek kadar uzun süre yaşayan nesneleri sık sık oluşturuyorsanız, pahalı 2. nesil koleksiyonlardan daha fazlası gerçekleşir. Mevcut nesneleri geri dönüştürerek veya nesneleri daha hızlı serbest bırakarak 2. nesil koleksiyonları azaltabilirsiniz.

Orta vadeli yaşam süresine sahip nesnelerin yaygın bir örneği, bir kullanıcının kaydırarak geçtiği bir listedeki öğeleri görüntülemek için kullanılan nesnelerdir. Listedeki öğeler görünüme kaydırıldığında nesneler oluşturuluyorsa ve öğeler görünümden kaydırıldığında artık bu nesnelere başvurulmuyorsa, uygulamanız genellikle çok sayıda 2. nesil koleksiyona sahiptir. Böyle durumlarda, kullanıcıya etkin olarak gösterilen veriler için bir nesne kümesini önceden ayırabilir ve yeniden kullanabilir ve listedeki öğeler görüntülendiğinde bilgileri yüklemek için kısa süreli nesneler kullanabilirsiniz.

Kısa ömürleri olan büyük boyutlu nesnelerden kaçınarak 2. nesil koleksiyonları azaltın

85 KB veya daha büyük olan tüm nesneler büyük nesne yığınında (LOH) ayrılır ve 2. nesil kapsamında toplanır. Arabellekler gibi 85 KB'tan büyük geçici değişkenleriniz varsa, 2. nesil bir koleksiyon bunları temizler. Geçici değişkenlerin 85 KB'ın altına sınırlandırılması, uygulamanızdaki 2. nesil koleksiyonların sayısını azaltır. Yaygın yöntemlerden biri, büyük geçici bellek tahsislerinden kaçınmak için bir bellek havuzu oluşturmak ve havuzdaki nesneleri yeniden kullanmaktır.

Referans açısından zengin nesnelerden kaçının

Çöp toplayıcı, uygulamanızdaki köklerden başlayarak nesneler arasındaki başvuruları izleyerek hangi nesnelerin canlı olduğunu belirler. Daha fazla bilgi için bkz. Çöp toplama sırasında ne olur? Bir nesne birçok başvuru içeriyorsa, çöp toplayıcının yapması gereken daha fazla iş vardır. Özellikle büyük nesnelerde yaygın kullanılan bir teknik, başvuru açısından zengin nesneleri başvuru içermeyen nesnelere dönüştürmektir. Örneğin, bir referans saklamak yerine bir dizin saklayın. Tabii ki bu teknik yalnızca mantıksal olarak mümkün olduğunda çalışır.

Nesne başvurularını dizinlerle değiştirmek, uygulamanızda kesintiye neden olan ve karmaşık bir değişiklik olabilir ve çok sayıda başvuruya sahip büyük nesneler için en etkili olandır. Bunu yalnızca uygulamanızda başvuru amaçlı ağır nesnelerle ilgili büyük çöp toplama sürelerini fark ediyorsanız yapın.