Oyun Motorunda Garbage Collection: FPS Düşüşünün Gizli Sebebi
Oyun oynarken aniden FPS düştüğünü, sonra normale döndüğünü fark ettin mi? Çoğu zaman bunun sebebi grafik kartı değil, bellekte çöp toplama işlemidir.
Garbage Collection (GC), programlama dilinin artık kullanılmayan belleği otomatik olarak temizlemesidir. C# ve Java gibi diller bunu kendi başlarına yapar. Oyun motorunda her frame'de yüzlerce nesne oluşturulup silinirse, GC bir anda devreye girerek tüm işlemi dondurur. Bu anlık duraklama FPS'i ciddi şekilde düşürür.
Unity'de örnek verelim. Aşağıdaki kod her frame'de yeni bir liste oluşturur:
1void Update() {2List<Enemy> enemies = new List<Enemy>(); // Her frame yeni liste3for (int i = 0; i < 100; i++) {4enemies.Add(new Enemy());5}6}Bu kodu 60 frame boyunca çalıştırırsan, 6000 liste nesnesi bellekte birikir. Bir noktada GC uyandığında, tüm bu nesneleri temizlemek için oyun 10-50 milisaniye donabilir. 60 FPS'de bir frame 16 ms'dir; bu süre çıkılırsa FPS'in yarısına düşer.
Listeyi frame dışında oluştur ve yeniden kullan:
1private List<Enemy> enemies = new List<Enemy>();23void Update() {4enemies.Clear(); // Listeyi temizle, yeniden oluşturma5for (int i = 0; i < 100; i++) {6enemies.Add(new Enemy());7}8}Bu şekilde liste bir kez ayrılır, içeriği değişir ama yeni bellek talep etmez. GC basınızı büyük ölçüde azaltır.
String birleştirmelerinde de aynı sorun oluşur. string text = "HP: " + hp; yerine string text = string.Format("HP: {0}", hp); veya string pool kullan. Object pooling tekniğiyle ise mermi, efekt gibi sık oluşturulan nesneleri önceden havuzda hazırla, silinme yerine deaktif et.
Unity Profiler'da GC.Alloc metriğini izle. Eğer her frame artıyorsa, yeni bellek tahsisatı yapılıyor demektir. Bunu sıfıra yaklaştırman oyunun akıcılığını önemli ölçüde iyileştirir.
0 yorum