Коли і чому потрібен клас Pool для розміщення об'єктів?


12

Я вивчав opengl es і приклад, який я бачив, використовував клас "Pool", щоб слідкувати за подіями на дотику та клавіатурі.

Невже хтось може пояснити, як і навіщо потрібен клас пулу. З того, що я читав, це було пов'язане зі збиранням сміття та обмеженням кількості вхідних класів.

Це все здається мені трохи абстрактним, тому, якщо хтось міг би пояснити, що відбувається, я би вдячний, я вставлю тут якийсь код:

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

Дякую!

Відповіді:


17

Басейни використовуються, коли кількість об'єктів різко коливатиметься, і використовується для зменшення обсягу розподілу пам'яті та збирання сміття.

Використовуючи пул, стандартний новий Object (), який виділяє нову пам'ять, замінюється витягуванням вже виділеного об'єкта з пулу. Це набагато швидше, навіть якщо ви переходите та скидаєте кожну змінну в старому об'єкті за замовчуванням.

Якщо ви створюєте новий елемент кожного разу, у вас є величезна надмірна голова, оскільки для кожного об'єкта потрібно виділити пам'ять. Крім того, оскільки ви створюєте так багато об'єктів, ви повинні часто їх прибирати, що призводить до того, що сміттєзбірник дуже часто запускається, що ще більше шкодить їх продуктивності.

Поширений приклад - кулі.

Для FPS на екрані може бути 0 куль, потім 1000 наступної секунди, а потім 0 ​​знову друга секунда після цього. Якби ви створювали нову кулю для кожної стрілянини, постійне розподілення пам'яті було б надзвичайно інтенсивним. Крім того, сміттєзбірник повинен відстежувати всі ці випадки та періодично прибирати очищення, що займає ще більше часу.

Якщо у вас є пул з 5000 куль і лише оновлюєте та взаємодієте з тими, які не є у списку freeObjects, у вас є лише 5000 загальних виділень незалежно від того, скільки триває перестрілка замість 1 розподілу на кулю. Також сміттєзбірник повинен працювати лише після того, як будь-яка можливість пожежі закінчиться. Взаємодія з пам'яттю відбувається дуже повільно, тому це робить величезний вплив на продуктивність і забезпечує навантаження навантаження рівномірно, запобігаючи заїкання частоти кадрів.


Тому я думаю, що клас пулу для ефектів частинок буде надзвичайно важливим, чи не так?
mathacka

Так, саме для таких басейнів ситуацій було розроблено.
ClassicThunder

Чи краще практика мати клас класів, це власні об'єкти або використовувати фабрику? Тобто Object.getObject () vs ObjectFactory.getObject ()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.