Quand et pourquoi une classe Pool est-elle nécessaire pour contenir des objets?

12

J'ai étudié l'opengl es et un exemple que j'ai vu utilisait une classe "Pool" pour garder une trace des événements tactiles et clavier.

Quelqu'un pourrait-il expliquer comment et pourquoi un cours de billard est nécessaire? D'après ce que je lisais, cela avait quelque chose à voir avec la collecte des ordures et la limitation du nombre de classes d'entrée créées.

Tout cela me semble un peu abstrait, donc si quelqu'un pouvait expliquer ce qui se passe, je l'apprécierais, je collerai du code ici:

    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);

Merci!

mathacka
la source

Réponses:

17

Les pools sont utilisés lorsque le nombre d'objets fluctue considérablement et sont utilisés pour réduire la quantité d'allocation de mémoire et la récupération de place.

En utilisant un pool, le nouvel objet standard () qui alloue de la nouvelle mémoire est remplacé par l'extraction d'un objet déjà alloué du pool. C'est beaucoup plus rapide même si vous réinitialisez chaque variable de l'ancien objet par défaut.

Si vous créez un nouvel élément à chaque fois, vous avez une énorme surcharge car la mémoire doit être allouée à chaque objet. De plus, parce que vous créez tant d'objets que vous devez les nettoyer souvent, ce qui entraîne l'exécution très fréquente du garbage collector, ce qui nuit encore davantage aux performances.

Un exemple courant est celui des balles.

Pour un FPS, il peut y avoir 0 puces à l'écran, puis 1000 la seconde suivante, puis 0 à nouveau la seconde après cela. Si vous deviez créer une nouvelle puce pour chaque tir déclenché, l'allocation de mémoire constante serait extrêmement gourmande en performances. De plus, le garbage collector doit suivre toutes ces instances et nettoyer périodiquement, ce qui prend encore plus de temps.

Si vous avez un pool de 5000 balles et que vous ne mettez à jour et n'interagissez qu'avec celles qui ne figurent pas dans la liste freeObjects, vous n'avez que 5000 allocations totales, quelle que soit la durée du combat, au lieu d'une allocation par balle. De plus, le ramasse-miettes ne doit s'exécuter qu'une fois la possibilité d'un échange de tirs terminée. L'interaction avec la mémoire est très lente, ce qui a un impact énorme sur les performances et garantit que la charge de travail est répartie uniformément, empêchant les bégaiements de la fréquence d'images.

ClassicThunder
la source
Je pense donc qu'une classe de pool pour les effets de particules serait extrêmement essentielle, ai-je raison?
mathacka
Oui, c'est exactement pour cela que les pools de situations ont été conçus.
ClassicThunder
Est-il préférable d'avoir un pool de classes avec ses propres objets ou d'utiliser une fabrique? C'est-à-dire Object.getObject () vs ObjectFactory.getObject ()