2

シミュレーション ループで、複数のメソッドを持つクラスのメソッドを頻繁に呼び出す必要があります。

これらのメソッドの一部は、情報を格納するために一時オブジェクトにアクセスする必要があります。メソッドを終了すると、保存されたデータは不要になります。例えば:

Class class {      
  method1() {
        ...
        SomeObject temp = new SomeObject();
       ...
  }

  method2() {
        ...
        SomeObject temp = new SomeObject();
        SomeObject temp2 = new SomeObject();
        ...
  }
}

可能な限り最適化する必要があります。最も費用のかかる (除去可能な) 問題は、割り当てが多すぎることです。これらのオブジェクトに必要なスペースを毎回割り当てないほうがよいと思うので、それらを保持したいと思います。

それらを静的な方法で保存する方が効率的ですか?お気に入り:

Class class {
  private (static?) SomeObject temp;
  private (static?) SomeObject temp2;

  methods...
}

それとももっと良い方法がありますか?ご協力ありがとうございました!

回答に基づいて編集: メモリフットプリントが実際の問題ではなく、ガベージコレクションが混乱を解消しています。SomeObject は Point2D に似たクラスであり、メモリを消費するものはありません (私の意見では)。(最終的に静的な)クラスレベルのオブジェクトをプレースホルダーとして使用する方が良いのか、それとも私が認識していないより高度な方法を使用する方が良いのかはわかりません。

4

4 に答える 4

3

temptemp2は、それ自体はオブジェクトではなく、 型のオブジェクトを指す変数であることに注意してくださいSomeObject。あなたがそれを計画している方法では、唯一の違いはそれでありtemptemp2ローカル変数ではなくインスタンス変数になります。通話中

temp = new SomeObject();

まだSomeObjectヒープに新しいものを割り当てます。

さらに、それらをローカル変数ではなく静的変数またはインスタンス変数にすると、最後に割り当てられたSomeObjects が強力に到達可能な状態に保たれ (インスタンスがインスタンス変数のスコープ内にある限りclass)、変数が再割り当てされるまでガベージ コレクションが行われなくなります。

この方法での最適化はおそらく効果的ではありません。現在、temptemp2が範囲外にSomeObjectなると、それらが指す はガベージ コレクションの対象になります。

それでもメモリの最適化に関心がある場合はSomeObject、保持している情報をキャッシュする方法についてアドバイスを得るために、 が何であるかを示す必要があります。

于 2011-09-21T20:34:33.147 に答える
3

この時期尚早な最適化の例には注意が必要です。通常、コードがより複雑になる (そして複雑になるとバグが発生しやすくなる)、読みにくくなる、バグが発生する可能性がある、期待した速度が得られないなどの欠点があります。 2D 点を表すような単純なオブジェクトの場合再利用の心配はありません。通常、再利用は、大量のメモリを使用している場合、長くて高価なコンストラクターを回避している場合、または頻繁に実行されるタイトなループからオブジェクトの構築を引き出している場合に、最も効果的です。

あなたが試すことができるいくつかの異なる戦略:

責任を呼び出し元にプッシュする1 つの方法は、呼び出し元に事前に初期化されたオブジェクトを渡させ、メソッド パラメータを最終的なものにすることです。ただし、これが機能するかどうかは、オブジェクトで何をする必要があるかによって異なります。

メソッド パラメーターとしての一時オブジェクトへのポインター別の方法は、呼び出し元にパラメーターとしてオブジェクトとして渡すことです。これは、基本的に、メソッドが一時的な格納を行うオブジェクトへのポインターになることを目的としています。この手法は C++ でより一般的に使用されていると思いますが、同様に機能しますが、グラフィックス プログラミングのような場所で時々見られます。

オブジェクト プール一時オブジェクトを再利用する一般的な方法の 1 つは、「使用可能な」オブジェクトの固定バンクからオブジェクトが割り当てられるオブジェクト プールを使用することです。これにはいくらかのオーバーヘッドがありますが、オブジェクトが大きく、頻繁に短期間しか使用されず、メモリの断片化が懸念される場合は、オーバーヘッドを考慮する価値があるほど十分に小さい可能性があります。

メンバー変数メソッドへの同時呼び出しを気にしない場合 (または同期を使用してそれを防止している場合) は、ストレージ用のクラスのメンバー変数を作成することにより、「ローカル静的」変数の C++ 主義をエミュレートできます。 . これにより、コードが読みにくくなり、変数を使用してコードの他の部分に偶発的に干渉する余地がわずかに増えますが、オブジェクト プールよりもオーバーヘッドが低く、メソッド シグネチャを変更する必要はありません。これを行う場合、必要に応じて、変数にtransientキーワードを使用して、変数をシリアル化する必要がないことを示すこともできます。

メソッドも静的でない限り、一時的な静的変数を敬遠します。これは、プログラムの実行中ずっと望ましくないメモリオーバーヘッドが発生する可能性があり、この目的のメンバー変数と同じ欠点がありますx2(複数同じクラスのインスタンス)

于 2011-09-21T21:58:57.427 に答える
1

これらのオブジェクトの大きさ。クラスレベルのオブジェクトを持つことができるように思えます(必ずしも静的ではありません。それについては後で説明します)。SomeObject の場合、その内容をパージするメソッドを使用できます。1 つの場所での使用が終了したら、メソッドを呼び出して内容を消去します。

静的な限り、複数の呼び出し元がこのクラスを使用し、異なる値を持つことはありますか? その場合は、静的を使用しないでください。

于 2011-09-21T20:35:12.553 に答える
1

まず、本当にこの問題があるかどうかを確認する必要があります。ガベージ コレクターの利点は、すべての一時オブジェクトを自動的に処理することです。

とにかく、シングル スレッド アプリケーションを実行していて、常に最大でも MAX_OBJECTS しか使用していないとします。1 つの解決策は次のようになります。

public class ObjectPool {

    private final int MAX_OBJECTS = 5;
    private final Object [] pool = new Object [MAX_OBJECTS];

    private int position = 0;

    public Object getObject() {

        // advance to the next object
        position = (position + 1) % MAX_OBJECTS;

        // check and create new object if needed
        if(pool[position] == null) {
            pool[position] = new Object();
        }

        // return next object
        return pool[position];
    }

    // make it a singleton
    private ObjectPool() {}
    private static final ObjectPool instance = new ObjectPool();
    public static ObjectPool getInstance() { return instance;}


}

そして、ここに使用例があります:

public class ObjectPoolTest {

public static void main(String[] args) {
    for(int n = 0; n < 6; n++) {
        Object o = ObjectPool.getInstance().getObject();
        System.out.println(o.hashCode());
    }
}

}

出力は次のとおりです。

0) 1660364311
1) 1340465859
2) 2106235183
3) 374283533
4) 603737068
5) 1660364311

最初と最後の数字が同じであることがわかります。MAX_OBJECTS + 1 回の繰り返しは、同じ一時オブジェクトを返します。

于 2011-09-21T21:04:24.733 に答える