Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Unity'de Addressable Assets ile Memory Yönetimi Yapayım Derken, Asset Bundle'ların Asenkron Yüklenmesi Hayatımı Kararttı

asternix

Üye
Katılım
14 Mart 2026
Mesajlar
15
Kafayı yiyecektim arkadaş. Şaka gibi ama, "memory leak" diye diye kendi projemde tam bir bellek katliamına sebep oldum. Her şey Addressable Assets sistemiyle daha temiz, daha kontrollü bir memory yönetimi yapma hevesiyle başladı. "Artık Resources klasörüne elveda, modern çözümler kullanacağım!" dedim. Meğer ben modern çözümlerin tuzağına düşmüşüm.

🛠️ Güzel Başlangıç, Her Şey Toz Pembe

İlk başta mükemmeldi. Asset'leri grupladım, etiketledim, Addressables.LoadAssetAsync() ile yüklemeye başladım. Performans harikaydı, build'ler düzenli, her şey yolunda gibiydi. "Neden daha önce kullanmadım ki?" diye kendime söyleniyordum. Ta ki...

📈 Profiler Kabusu ve Gizli Bellek Canavarı

Oyunun belirli bir bölümünde, sürekli aynı sahneye girip çıkınca, Memory Profiler penceresinde gördüğüm manzara içler acısıydı. AssetBundle'lar ve Texture'lar gözle görülür şekilde birikiyor, ama ben Addressables.Release() ve hatta Addressables.ReleaseInstance() kullanıyordum! StackOverflow'da bile net bir cevap bulamadım, herkes "doğru kullanıyorsan sorun olmaz" diyordu. Meğerse sorun şuradaymış:

C#:
// İşte o lanet olası, masum görünen kod parçası:
var asyncHandle = Addressables.LoadAssetAsync<GameObject>("MyPrefab");
asyncHandle.Completed += (handle) =>
{
    Instantiate(handle.Result);
    // Addressables.Release(handle); // BUNU UNUTMAK ÖLÜM!
};

Evet. O Completed event'ının içinde, handle'ı serbest bırakmayı UNUTUYORDUM. Ama daha kötüsü vardı...

🔗 Reference Zinciri ve Koleksiyon Tuzağı

Asenkron işlemlerin dönüş tipi olan AsyncOperationHandle, bir struct. Onu bir class içindeki liste veya dictionary'de saklamaya kalktığınız anda, işler çığırından çıkıyor. Handle'ın "hayatta" kalması, arka plandaki asset'in de bellekte kalması anlamına geliyor. Şöyle bir şey yapmışım farkında olmadan:

C#:
List<AsyncOperationHandle> _ongoingLoads = new List<AsyncOperationHandle>();

// Her yüklemede listeye ekliyordum...
var handle = Addressables.LoadAssetAsync<Texture2D>("bgImage");
_ongoingLoads.Add(handle); // BU SATIR ÖLDÜRÜCÜ DARBE!
// Ve bu listeyi temizlemeyi hep erteliyordum...

💡 Kurtuluş Yolu: Task'lar, Awaitable'lar ve Titizlik

Çözüm, disiplinli olmakta ve Addressables'ın .Task özelliğini veya Unity 2023'le gelen daha iyi awaitable desteğini kullanmakta yatıyormuş. Artık şöyle yapıyorum:

C#:
public async UniTask<GameObject> LoadAndForget(string key)
{
    var handle = Addressables.LoadAssetAsync<GameObject>(key);
    var obj = await handle.Task; // Task tamamlanana kadar bekle
    var instance = Instantiate(obj);
    Addressables.Release(handle); // HEMEN SERBEST BIRAK!
    return instance;
}

Ayrıca, Addressables penceresindeki Analyze tool'u ve Event Viewer'ı düzenli çalıştırmak, kimin neyi tuttuğunu görmek şart.

Sonuç olarak, Addressable Assets güçlü bir silah, ama tetiği çekmeden önce iki kere düşünmek gerekiyor. Asenkron programming'in "fire and forget" mantığı, burada tam bir hafıza (ve hayat) düşmanına dönüşebiliyor.

Siz de benzer bir Addressables veya AssetBundle kabusu yaşadınız mı? Özellikle sahne geçişlerinde memory temizliği için hangi pattern'leri kullanıyorsunuz? "Ben şöyle yapıyorum, çok rahatım" diyen var mı?
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri