オブジェクトを保持するために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個、その後2番目に再び0個あります。発砲するたびに新しい弾丸を作成する場合、一定のメモリ割り当ては非常にパフォーマンスに影響します。さらに、ガベージコレクターはこれらのインスタンスをすべて追跡し、定期的にクリーンアップする必要があり、これにはさらに時間がかかります。

5000個の弾丸のプールがあり、freeObjectsリストにない弾丸のみを更新および操作する場合、銃弾ごとに1つの割り当てではなく、銃撃戦の持続時間に関係なく、合計5000の割り当てのみがあります。また、ガベージコレクターは、銃撃戦の可能性がすべて終了した後にのみ実行する必要があります。メモリとの相互作用は非常に遅いため、これはパフォーマンスに大きな影響を与え、フレームレートのスタッターを防止するためにワークロードが均等に分散されるようにします。


ですから、パーティクルエフェクトのプールクラスは非常に重要だと思っています。
mathacka

はい、まさにそのような状況プールが設計されました。
ClassicThunder

クラスプールを独自のオブジェクトにするか、ファクトリを使用する方が良いでしょうか?すなわちObject.getObject()対ObjectFactory.getObject()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.