0

ローカル変数をメモリに配置する方法を知りたいですか? method1 では、変数は一度メモリに配置されますか? method2 では、毎回メモリ内の古い場所を削除した後、変数は場所を取りますか?

public void method1() {
    Object obj = null;
    for(.....) {
        obj = come from other-->

    }
}

public void method2() {
    for(.....) {
        Object obj = come from other-->
    }
}
4

5 に答える 5

2

レジスタ内またはメモリ内にある可能性のあるローカル変数があります。

ローカル変数が参照するオブジェクトもあります。これは、どちらの場合も反復ごとに作成されます。

それらは事実上同じですが、ローカル変数のスコープを狭めるため、可能であれば2番目のケースを好みます。

于 2012-09-25T10:45:53.943 に答える
1

各メソッド呼び出しは、呼び出しスタックに格納されているアクティベーションレコードに関連付けられています。アクティベーションレコードは、メソッドレベルの変数に対応するヒープ内のメモリブロックへの参照を保持します。メソッド呼び出しが呼び出し元に戻ると、このアクティベーションレコードはスタックから削除され、メモリ参照をガベージコレクションできる可能性があります。

あなたの場合、

  1. 最初のメソッドではobj、その参照は呼び出しスタックに格納され、実際のメモリはヒープ上にあり、これはメソッド呼び出しごとに1回実行されます。
  2. 2番目のobjメソッドのforループは、反復ごとに1回作成され、各反復の終了時にスコープ外になります。したがって、参照とヒープ上のメモリは、反復ごとに割り当てられます。
于 2012-09-25T10:48:51.033 に答える
1

ローカル変数は、通常 (最適化されていない限り) スタック メモリに保持されます。ただし、プリミティブ値または参照のみを格納できます。参照されるオブジェクト自体は通常、ヒープに割り当てられます (JIT 最適化に関係なく)。

スタック ベースのメモリ割り当て (ウィキペディア)とヒープベースのメモリ割り当て (ウィキペディア)を参照してください。

スタックに値を格納するのは非常に安価です。関数呼び出しと同様に、リターン ポインターをスタックに格納します。スタック ポインタをインクリメントするだけで済みます (専用の CPU レジスタをインクリメントするのは高速であることが想像できます!)。

オブジェクト自体が異なります。理論的には、次の反復では値が不要であることを明確に示しているため、一部の Java コンパイラまたは JIT は 2 番目のコードをより適切に最適化できる可能性があることに注意してください。(さらに優れたコンパイラは、これ自体を理解できるはずです。)

一般に、最新のコンパイラは、どちらの場合も最適化後に同じマシン コードを生成する必要があります。(これは JIT コンパイラで発生する可能性があるため、Java バイトコードは依然として違いを示す可能性があります)。

とにかく、ローカル変数を再利用して過度に最適化しようとしないでください。代わりに、明示的なコードを記述し、コンパイラに最適化させます。ループ内で新鮮な変数を使用することにより、どこでも再利用されないことを明示します。これにより、プログラミング エラーを防ぐことができます。

于 2012-09-25T10:51:36.953 に答える
0

どちらの場合も、反復ごとに新しいオブジェクトがメモリに作成されると思います。最も「最近の」オブジェクト以外への参照がないことに気付くのは、ガベージコレクター次第です。

于 2012-09-25T10:48:41.817 に答える
0

メソッド 1 とメソッド 2 のオブジェクトはヒープに配置されますが、Java コンパイラはエスケープ解析を実行して、メソッドの実行後にこの種のオブジェクトを解放する必要があるかどうかを判断します。エスケープ解析は Java Standard Edition 6 で実装されています

于 2012-09-25T10:51:47.820 に答える