什么时候以及为什么需要一个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);

谢谢!

Answers:


17

当对象数量急剧变化时,将使用池,并用于减少内存分配和垃圾收集的数量。

使用池将分配新内存的标准new Object()替换为从池中拉出已分配的对象。即使您将旧对象中的每个变量都重置为默认值,这也要快得多。

如果每次创建一个新项目时都会有大量开销,因为必须为每个对象分配内存。另外,由于要创建的对象太多,因此必须经常清理它们,这会使垃圾收集器经常运行,从而进一步损害性能。

一个常见的例子是子弹。

对于FPS,屏幕上可能有0个项目符号,然后第二秒为1000,然后第二秒又为0。如果要为每一个发射的项目创建一个新项目符号,则恒定的内存分配将非常耗费性能。此外,垃圾收集器还必须跟踪所有这些实例并定期清理,这需要更多时间。

如果您有5000个子弹池,并且仅与freeObjects列表中未更新的子弹进行更新并进行交互,则无论交战持续多长时间,您只有5000个子弹分配,而不是每个子弹分配1个子弹。同样,垃圾收集器只需要在任何可能的灭火结束后运行。与内存的交互非常缓慢,因此这会对性能产生巨大影响,并确保工作负载均匀分布,从而防止帧速率停顿。


因此,我认为用于粒子效果的池类非常重要,对吗?
mathacka

是的,正是针对这种情况而设计的。
ClassicThunder13年

将类池设为自己的对象还是使用工厂是更好的做法?即Object.getObject()与ObjectFactory.getObject()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.