Paylaşılan Mülkiyet Nadiren Anlamda
Bu cevap biraz teğet olabilir, ancak sormak zorundayım, sahip olmanın paylaşılması için bir kullanıcı sonu açısından kaç vaka mantıklı ? En azından çalıştığım alanlarda neredeyse hiç yoktu çünkü aksi takdirde kullanıcının bir yerden bir kez bir şeyi kaldırması gerekmediği, ancak kaynak gerçekte olmadan önce açıkça ilgili tüm sahiplerden kaldırması gerektiği anlamına gelir. sistemden kaldırıldı.
Başka bir iş parçacığı gibi, başka bir şey buna erişmeye devam ederken kaynakların yok edilmesini önlemek genellikle daha düşük düzeyli bir mühendislik fikridir. Genellikle bir kullanıcı yazılımdan bir şey kapatmak / kaldırmak / silmek istediğinde, mümkün olan en kısa zamanda kaldırılması gerekir (kaldırılması güvenli olduğunda) ve kesinlikle etrafta dolaşmamalı ve kaynak sızıntısına neden olmamalıdır. uygulama çalışıyor.
Örnek olarak, bir video oyunundaki oyun varlığı, malzeme kitaplığındaki bir malzemeye referans verebilir. Başka bir iş parçacığı hala oyun varlığı tarafından başvurulan malzemeye erişirken, malzeme bir iş parçacığında malzeme kitaplığından kaldırılırsa, kesinlikle sarkan bir işaretçi çökmesini istemiyoruz. Ancak bu, oyun varlıklarının referans aldıkları malzemelerin sahipliğini malzeme kütüphanesiyle paylaşmasının bir anlamı olmadığı anlamına gelmez . Kullanıcıyı, malzemeyi hem varlıktan hem de malzeme kitaplığından açıkça kaldırmaya zorlamak istemiyoruz. Sadece malzemelerin tek mantıklı sahibi olan malzeme kütüphanesinden materyalin kaldırılmadığından emin olmak istiyoruz.
Kaynak Sızıntıları
Yine de yazılımdaki tüm bileşenler için GC'yi benimseyen eski bir ekiple çalıştım. Ve bu, diğer iş parçacıkları hala bunlara erişirken hiçbir zaman kaynakların yok edilmemesini sağlamada gerçekten yardımcı olsa da, bunun yerine kaynak sızıntılarından payımızı aldık .
Ve bunlar, bir saatlik bir oturumdan sonra bir kilobayt bellek sızıntısı gibi, yalnızca geliştiricileri üzen türden önemsiz kaynak sızıntıları değildi. Bunlar, aktif bir oturumda genellikle gigabayt bellek gibi epik sızıntılardı ve hata raporlarına yol açtı. Çünkü şimdi bir kaynağın sahipliğine, örneğin 8 farklı bölüm arasında referans verildiğinde (ve dolayısıyla sahiplikte paylaşıldığında), o zaman kaynağın kaldırılmasını isteyen kullanıcıya yanıt olarak kaynağın kaldırılması yalnızca bir tane alır sızdırılmış ve muhtemelen süresiz olarak.
Bu yüzden hiçbir zaman büyük bir GC hayranı ya da herhangi bir geniş çapta uygulanan referans sayımı olmadım çünkü sızdıran yazılım oluşturmayı ne kadar kolay hale getirdiler. Önceden, tespit edilmesi kolay olan sarkan bir işaretçi çökmesi, test radarı altında kolayca uçabilen, algılanması çok zor bir kaynak sızıntısına dönüşür.
Dil / kütüphane bunları sağlarsa zayıf referanslar bu sorunu hafifletebilir, ancak uygun olduğunda zayıf referansları tutarlı bir şekilde kullanabilmek için karışık beceri setleri geliştiricilerinden oluşan bir ekibin bulunmasını zor buldum. Ve bu zorluk sadece iç ekiple değil, yazılımımız için her eklenti geliştiricisiyle de ilgiliydi. Onlar da kolayca bir suçlu olarak eklentiye geri izlemeyi zorlaştıracak şekilde bir nesneye kalıcı bir referans depolayarak sistemin kaynak sızdırmasına neden olabilir, bu yüzden bizim yazılım kaynaklarımızdan kaynaklanan hata raporlarından aslan payımızı aldık çünkü kaynak kodu kontrolümüz dışında olan bir eklenti bu pahalı kaynaklara referans veremedi.
Çözüm: Ertelenmiş, Periyodik Kaldırma
Bu yüzden, daha sonra bana her iki dünyadan bulduğum en iyi şeyi veren kişisel projelerime uyguladığım çözümüm referencing=ownership
, kaynakların hala yok edilmesini erteleyen kavramı ortadan kaldırmaktı .
Sonuç olarak, artık kullanıcı bir kaynağın kaldırılmasına neden olan bir şey yaptığında, API yalnızca kaynağı kaldırma açısından ifade edilir:
ecs->remove(component);
... kullanıcı-son mantığını çok basit bir şekilde modeller. Ancak, işlem aşamalarında aynı bileşene aynı anda erişebilecekleri başka sistem iş parçacıkları varsa, kaynak (bileşen) hemen kaldırılamayabilir.
Böylece bu işleme iplikleri daha sonra burada ve orada bir çöp toplayıcısına benzeyen bir ipliğin uyanıp " dünyayı durdurmasına " ve ipliklerin bitene kadar bu bileşenlerin işlenmesinden kilitlenmesi sırasında çıkarılması istenen tüm kaynakları yok etmesine izin veren zaman verir. . Bunu, burada yapılması gereken iş miktarının genellikle minimum olması ve kare hızlarında belirgin bir şekilde kesilmemesi için ayarladım.
Şimdi bunun denenmiş ve test edilmiş ve iyi belgelenmiş bir yöntem olduğunu söyleyemem, ancak birkaç yıldır hiç baş ağrısı ve kaynak sızıntısı olmadan kullandığım bir şey. Mimarinizin bu tür eşzamanlılık modeline uyması mümkün olduğunda, GC veya ref sayımından çok daha az ağır olduğu ve test radarı altında bu tür kaynak sızıntılarını riske atmadığı için böyle yaklaşımları keşfetmenizi öneririm.
Ref sayımı veya GC'nin yararlı olduğunu bulduğum tek yer kalıcı veri yapıları içindir. Bu durumda, veri yapısı bölgesi, kullanıcı sonu endişelerinden çok uzaktır ve orada, her değişmez kopyanın aynı değiştirilmemiş verilerin sahipliğini potansiyel olarak paylaşması mantıklıdır.