---
title: "Nesne Havuzu (Object Pool) ile Oyunda Kare Düşmesini Önlemek"
url: "https://cilginyazilim.com/blog/nesne-havuzu-object-pool-oyun"
description: "Nesne havuzu deseni oyunlarda kare düşmesini nasıl önler? Çöp toplayıcı baskısı, havuz uygulaması, sızıntı riskleri ve ölçüm yöntemleriyle pratik anlatım."
published: "2026-10-27T10:00:00+03:00"
modified: "2026-10-27T10:00:03+03:00"
author: "Çılgın Yazılım"
category: "Mobil ve Oyun Geliştirme"
tags: ["javascript", "oyun geliştirme", "unity", "performans", "optimizasyon", "profil çıkarma", "kare hızı", "bellek yönetimi", "çöp toplayıcı", "garbage collector", "tasarım deseni", "nesne havuzu", "object pool"]
site: "Çılgın Yazılım"
language: "tr"
---

# Nesne Havuzu (Object Pool) ile Oyunda Kare Düşmesini Önlemek

Her mermi için yeni nesne üretmek çöp toplayıcıyı tetikler ve oyun takılır. Nesne havuzu bu maliyeti nasıl sıfırlar?

**Nesne havuzu**, sık üretilip sık yok edilen nesneleri her seferinde yeniden yaratmak yerine, önceden hazırlanmış bir koleksiyondan ödünç alıp iş bitince geri vermektir. Oyun geliştirmede bu desen bir stil tercihi değil, çoğu zaman akıcı kare hızının önkoşuludur.

![Nesne havuzunun tahsis grafiğine etkisi](https://cilginyazilim.com/uploads/blog/2026/08/nesne-havuzu-object-pool-oyun-ozet.png)
*Testere dişi şeklindeki bellek grafiği, havuz ihtiyacının en net işaretidir.*

## Problem: çöp toplayıcı duraklaması

Bir nişancı oyununda saniyede 60 kare çiziliyorsa ve her karede on mermi doğuyorsa, dakikada 36.000 kısa ömürlü nesne üretiyorsunuz demektir. Bu nesneler hemen ölür, ama ölmeleri bedavaya gelmez: çöp toplayıcı belirli aralıklarla devreye girip belleği tarar ve bu sırada oyun donar. Duraklama 16 milisaniyeyi aştığı anda oyuncu bunu *takılma* olarak hisseder.

> Ortalama kare süresi iyi görünse bile takılma yaşanabilir. Çöp toplayıcı duraklamaları ortalamayı değil, **en kötü yüzdelik dilimi** (p99 kare süresi) bozar. Ölçerken ortalamaya değil, en kötü kareye bakın.

## Havuzun iskeleti

Havuz üç işten sorumludur: hazırla, ödünç ver, geri al. Aşağıdaki uygulama JavaScript ile yazıldı ama mantık her dilde aynıdır.

```javascript
class NesneHavuzu {
  /**
   * @param {Function} uret  Yeni nesne üreten fabrika
   * @param {Function} sifirla  Nesneyi ilk hâline döndüren fonksiyon
   * @param {number}   onIsitma  Başlangıçta kaç nesne hazırlansın
   */
  constructor(uret, sifirla, onIsitma = 64) {
    this.uret = uret;
    this.sifirla = sifirla;
    this.bosta = [];
    this.kullanimda = 0;

    // Ön ısıtma: oyun başlarken bir kez tahsis, oyun sırasında hiç
    for (let i = 0; i < onIsitma; i++) this.bosta.push(uret());
  }

  al() {
    this.kullanimda++;
    const nesne = this.bosta.pop();
    return nesne !== undefined ? nesne : this.uret();   // havuz boşsa büyüt
  }

  birak(nesne) {
    this.sifirla(nesne);
    this.bosta.push(nesne);
    this.kullanimda--;
  }

  get istatistik() {
    return { bosta: this.bosta.length, kullanimda: this.kullanimda };
  }
}
```

Kullanımı, mermi mantığını neredeyse hiç değiştirmez:

```javascript
const mermiHavuzu = new NesneHavuzu(
  () => ({ x: 0, y: 0, hiz: 0, aktif: false }),
  (m) => { m.x = 0; m.y = 0; m.hiz = 0; m.aktif = false; },
  256
);

function atesEt(x, y, hiz) {
  const m = mermiHavuzu.al();
  m.x = x; m.y = y; m.hiz = hiz; m.aktif = true;
  sahne.push(m);
}

function guncelle(dt) {
  for (let i = sahne.length - 1; i >= 0; i--) {
    const m = sahne[i];
    m.y -= m.hiz * dt;

    if (m.y < 0) {
      sahne.splice(i, 1);
      mermiHavuzu.birak(m);      // ← unutulursa havuz büyür, sızıntı olur
    }
  }
}
```

## En büyük risk: geri vermeyi unutmak

Havuzun getirdiği tek yeni hata sınıfı budur. Nesne ödünç alınır ama iade edilmezse havuz sürekli büyür ve elle yönetilen bir bellek sızıntısı elde edersiniz. İki savunma işe yarar: her karede `kullanimda` sayacını izlemek ve nesneyi iade eden kodu, onu alan kodun hemen yanında tutmak. Bu, farklı bellek modellerinde sahiplik kavramının neden bu kadar merkezî olduğunu da açıklar — konuyu [bellek yönetimi modelleri](https://cilginyazilim.com/blog/bellek-yonetimi-modelleri-gc-sahiplik-manuel) yazımızda ele almıştık.

## Sabit zaman adımıyla birlikte düşünün

Havuz, tahsis kaynaklı takılmayı çözer; ancak fizik hesabı kare süresine bağlıysa yavaş karelerde nesneler yine sıçrar. İki teknik birlikte kullanılmalıdır: havuz belleği sabitler, [sabit zaman adımı](https://cilginyazilim.com/blog/oyun-dongusunde-sabit-zaman-adimi-fizik-neden-kayiyor) ise hareketi sabitler.

## Ne zaman gerek yok?

Havuz da bir tür önbellektir; hangi katmanda ne kadar tutulacağını [toplu yükleme deseni](https://cilginyazilim.com/blog/toplu-yukleme-batch-loading-deseni) yazımızdaki gibi ölçerek belirlemek gerekir. Havuz her nesne için gerekmez. Ölçüt basittir: nesne **sık** üretiliyor mu ve **kısa** mı yaşıyor? İkisi birden doğruysa aday, biri yanlışsa gereksiz karmaşıklıktır. Menü ekranındaki düğmeler için havuz kurmak, kazanç sağlamadan kod okunurluğunu düşürür. Uzun ömürlü ama tahsisi pahalı kaynaklar (ağ bağlantısı, doku belleği) ise farklı bir desenle — tembel yükleme ve önbellek — yönetilmelidir.

## Ölçmeden karar vermeyin

```javascript
// En kötü kare süresini izlemek, ortalamadan çok daha bilgilendiricidir
let kareler = [];
function olc(dt) {
  kareler.push(dt);
  if (kareler.length === 600) {
    kareler.sort((a, b) => a - b);
    console.log('medyan', kareler[300].toFixed(2), 'p99', kareler[594].toFixed(2));
    kareler = [];
  }
}
```

Tarayıcı tarafında bellek davranışını görmek için [MDN bellek yönetimi belgeleri](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management) ve tarayıcının performans profil aracı birlikte kullanılmalıdır.

## Sonuç

Nesne havuzu, oyunlarda takılmanın en yaygın sebeplerinden birini — sık tahsis ve ardından gelen çöp toplayıcı duraklamasını — ortadan kaldırır. Uygulaması kırk satırdır, ama beraberinde tek bir disiplin gerektirir: aldığınız her nesneyi geri verin. Önce ölçün, testere dişi bir bellek grafiği görüyorsanız havuzu kurun, sonra en kötü kare süresini yeniden ölçüp kazancı kanıtlayın. Bir sonraki oyun döngünüzde saniyede kaç nesne doğduğunu bir kez sayın; sayı sizi şaşırtırsa doğru deseni bulmuşsunuz demektir.

## İlgili Yazılar

- [Push Bildirimi Tasarımı: Uygulama Silinmeden Bildirmek](https://cilginyazilim.com/blog/push-bildirimi-tasarimi-uygulama-silinmeden)

## Sıkça Sorulan Sorular

### Nesne havuzu her oyun için gerekli mi?

Hayır. Basit bir bulmaca oyununda kare başına birkaç nesne üretiliyorsa havuz kazanç getirmez, yalnızca karmaşıklık ekler. Havuz, saniyede yüzlerce kısa ömürlü nesne üreten sistemlerde (mermi, parçacık efekti, düşman dalgası) anlamlıdır.

### Havuz boyutunu nasıl seçmeliyim?

Oyunun en yoğun anındaki eşzamanlı nesne sayısını ölçün ve üzerine pay ekleyin. Havuz boşaldığında yeni nesne üretmesine izin veren esnek bir tasarım, yanlış tahmini ölümcül olmaktan çıkarır; sadece o anda bir tahsis maliyeti oluşur.

### Havuzdan alınan nesneyi sıfırlamayı unutursam ne olur?

Önceki kullanımdan kalan değerler yeni nesneye sızar ve son derece zor bulunan hatalar üretir: örneğin ölmüş bir düşmanın canı yeni düşmana geçer. Bu yüzden sıfırlama fonksiyonunu havuzun kendi sorumluluğunda tutmak, çağıran koda bırakmaktan güvenlidir.

### Çöp toplayıcısı olmayan dillerde havuz gerekli mi?

C++ veya Rust gibi dillerde çöp toplayıcı duraklaması yoktur, ama tahsis işleminin kendisi ve bellek parçalanması hâlâ maliyetlidir. Bu dillerde havuz, öngörülebilir bellek düzeni sağladığı için önbellek isabet oranını da artırır — gerekçe değişir, fayda kalır.

---

Kaynak: [Nesne Havuzu (Object Pool) ile Oyunda Kare Düşmesini Önlemek](https://cilginyazilim.com/blog/nesne-havuzu-object-pool-oyun)
