Nesneleri tutmak için bir Pool sınıfına ne zaman ve neden ihtiyaç duyulur?


12

Opengl es üzerinde çalışıyorum ve gördüğüm bir örnek dokunmatik ve klavye olaylarını takip etmek için bir "Havuz" sınıfı kullanmak olduğunu.

Birisi bir havuz dersine nasıl ve neden ihtiyaç duyulduğunu açıklayabilir mi? Ne okuyordum ki çöp toplama ve yapılan giriş sınıflarının sayısını sınırlamak ile ilgili bir şey vardı.

Bu benim için biraz soyut görünüyor, bu yüzden biri neler olup bittiğini açıklayabilirse, bunu takdir edeceğim, buraya bazı kod yapıştırırım:

    public Pool(PoolObjectFactory <> factory, int maxSize) {            
        this.factory = factory;         
        this.maxSize = maxSize;         
        this.freeObjects = new ArrayList < T > (maxSize);     
    }  
         
    public T newObject() {        
        T object = null ;        
        if (freeObjects.isEmpty())            
            object = factory.createObject();        
        else             
            object = freeObjects.remove(freeObjects.size() - 1);        
            return object;     
    } 

    public void free(T object) {         
        if (freeObjects.size() < maxSize)             
            freeObjects.add(object);     
    }

    PoolObjectFactory <TouchEvent> factory = new PoolObjectFactory <TouchEvent> () {
     
    @Override     
    public TouchEvent createObject() {         
         return new TouchEvent();     
    } 

    Pool <TouchEvent> touchEventPool = new Pool <TouchEvent> (factory, 50); 
    TouchEvent touchEvent = touchEventPool.newObject(); 
    . . . do something here . . . 
    touchEventPool.free(touchEvent);

Teşekkürler!

Yanıtlar:


17

Havuzlar, nesne sayısı önemli ölçüde dalgalanacağı zaman kullanılır ve bellek tahsisi ve çöp toplama miktarını azaltmak için kullanılır.

Bir havuz kullanıldığında, yeni bellek ayıran standart new Object (), önceden ayrılmış bir nesneyi havuzdan alarak değiştirilir. Yine de eski nesnedeki her değişkeni varsayılana sıfırlasanız bile bu çok daha hızlıdır.

Her seferinde büyük bir başınız olduğunda yeni bir öğe oluşturursanız, her nesne için bellek ayrılması gerekir. Ayrıca çok fazla nesne oluşturduğunuz için onları sık sık temizlemelisiniz, bu da çöp toplayıcının daha sık zarar vermesine neden olur.

Yaygın bir örnek mermidir.

Bir FPS için ekranda 0 mermi, ardından 1000 saniye sonra ve sonra 0 saniye sonra tekrar olabilir. Eğer ateşlenen her biri için yeni bir mermi yaratacak olsaydınız, sabit bellek tahsisi son derece performans yoğun olurdu. Buna ek olarak, çöp toplayıcının tüm bu örnekleri izlemesi ve periyodik olarak temizlemesi gerekir, bu da daha fazla zaman alır.

5000 mermi havuzunuz varsa ve yalnızca freeObjects listesinde olmayanları güncelleyip onlarla etkileşimde bulunuyorsanız, mermi başına 1 ayırma yerine yangınla mücadele ne kadar sürerse sürsün sadece 5000 toplam ayırmaya sahip olursunuz. Ayrıca çöp toplayıcının yalnızca herhangi bir yangın söndürme olasılığı sona erdiğinde çalışması gerekir. Bellekle etkileşim çok yavaştır, bu da performans üzerinde büyük bir etki yapar ve iş yükünün eşit dağıldığından emin olun ve kare hızı kesimlerini önler.


Parçacık efektleri için bir havuz dersinin son derece önemli olacağını düşünüyorum, değil mi?
mathacka

Evet, havuzlar için tam olarak bir tür durum tasarlandı.
ClassicThunder

Kendi nesneleri olan bir sınıf havuzuna sahip olmak veya bir fabrika kullanmak daha iyi bir uygulama mıdır? Ie Object.getObject () vs ObjectFactory.getObject ()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.