6

私は Android アプリに取り組んでおり、私が書いているメソッドが何度も呼び出される可能性があります。このメソッドでは、ユーザー インターフェイスを更新しています。メモリの使用とパフォーマンスは私にとって重要です。私の見方では、UI の変更には 2 つのオプションがあります。

1つ目は、毎回新しいものを作ることです。つまり、次のようなことです。

public void myMethod(){
new View().makeVisible();
}

2 つ目は、オブジェクトを変数としてグローバルに宣言し、メソッドで参照することです。これは次のようになります。

View myView = new View();

public void myMethod(){
myView.makeVisible();
}

明らかに、このメソッドが数回しか呼び出されない場合、違いは小さくなります。ただし、これを何度も呼び出す可能性があり、この方法で呼び出しまたは作成される変数が多数ある場合、2 番目の方法でパフォーマンスが向上しますか?

4

4 に答える 4

4

他の回答が示しているように、メソッド呼び出しごとに新しいオブジェクトを繰り返しインスタンス化するのではなく、同じオブジェクトを再利用すると、メモリ フットプリントが削減され、ガベージ コレクションに関するパフォーマンスが向上します。

しかし、実際には保守性について最初に考えます。同じオブジェクトを再利用すると、コードがはるかに複雑になります (また、バグが発生する可能性があります)。プログラミングの際に効率性を念頭に置いておくのは良いことですが、時期尚早の最適化はプロジェクトを複雑にし、開発を遅らせないようにしてください。

パフォーマンスとメモリ使用量懸念される場合は、同じものを再利用するとメリットがありますView

final View myView = new View(); //made final because it shouldn't be reassigned

本当にリソースを重視したい場合は、オブジェクトを遅延読み込みすることもできます。つまり、必要なときにだけ作成します。Suppliers.memoize(Supplier)ただし、その動作を手作業でコーディングするのではなく、グアバを使用してこれを処理することをお勧めします。

final Supplier<View> myViewSupplier = Suppliers.memoize(new Supplier<View>() {
    @Override
    public View get() {
        return new View();
    }
});

...

public void myMethod() {
    View myView = myViewSupplier.get(); //lazy-loads when first called
    myView.makeVisible();
}

ただし、この特定の状況ではおそらく極端です。

于 2012-06-03T23:33:57.173 に答える
1

純粋に効率だけで決定を下すべきではないと思います。代わりに、どの構成がモデル化しようとしているドメインをより適切に表しているかについてです。問うべき質問は、「View を使用するクラスの正しい構造はどれですか?」です。

インスタンス変数の使用はグローバルではありません。それを宣言するオブジェクトのコンテキスト内に含まれています。グローバルは OO に存在することは想定されていませんが、public static 変数はかなり近いものです。

最初に決定することは、「ビュー」インスタンスが、それを使用するクラス/メソッドの意図に対して論理的に属する場所です。それを使用するクラスが何らかのファクトリであり、「myMethod」がファクトリ メソッドである場合、はい、新しいインスタンスを返します。

「ビュー」がクラスの論理フィールドであり、その状態と動作をキャプチャして強化するのに何らかの形で役立つ場合、毎回新しいものを作成する理由はありません。単にその状態を維持し、既存のオブジェクトを操作します。

あなたの説明から、ある種のビューの状態を維持および更新しようとしているようです。毎回新しいオブジェクトを作成するのではなく、必要な状態に変更して再表示する方が理にかなっています。あなたのシナリオでは機能的に両方のアプローチが機能しているように見えるので、2番目の選択肢を取り、不要なオブジェクトの作成を避けます。

于 2012-06-03T23:54:50.517 に答える
0

グローバル変数はより効率的です。

新しいオブジェクトを作成すると、ビューが作成されて古いビューが置き換えられるたびに、古いビューのガベージ コレクションが必要になるため、メモリ フットプリントが大きくなります。グローバル変数を使用して同じビューを再利用すると、システムは新しいオブジェクトを作成して古いオブジェクトを収集するタスクを節約できます。

編集:グローバル変数は、オブジェクト自体ではなく、オブジェクトへの参照のみです。

于 2012-06-03T22:59:45.607 に答える
0

さて、すべてのコンストラクターに新しいインスタンスを作成させると、基本的に、絶対に必要ではない作業を再度実行することになります。私があなたの立場なら、グローバル変数オプションを使用してから、ビューをクリアし、可能であれば同じオブジェクトを再描画します。これにより、他の方法でメモリの割り当て解除と割り当てが繰り返される可能性が防止されます。そのため、新しいビューを継続的に割り当てる価値があるほどクリアに特にコストがかかると思わない限り、消去してください。

同じオブジェクトを再利用するもう 1 つの動機は、Java 仮想マシンの実装ではガベージ コレクションの使用方法が異なることです。変数がスコープ外になるとアクセスできなくなります。JVM に対応するメモリが解放されると、常に同じとは限りません。 . 別の方法を使用すると、多くのビューが順次割り当てられているインスタンスがあることがわかりますが、プロセスがしばらくアイドル状態になるまですべてのビューが解放されるわけではなく、事実上、アプリがまったく必要のないメモリを消費します。

于 2012-06-03T23:00:40.643 に答える