web-dev-qa-db-ja.com

Javaでオブジェクトを破壊する方法は?

私は次のオプションを使用したインタビューでこの質問に遭遇しました。

Javaでオブジェクトを破壊する方法は?

a. System.gc();  
b. Runtime.getRuntime.gc();  
c. object.delete();  
d. object.finalize();  
e. Java performs gc by itself, no need to do it manually.
  1. 答えはeである必要がありますか?

  2. eがなかったらどうしますか?それから?明らかにcは答えではありません。 aとbはアプリケーション全体に対してgcを実行します(1つのオブジェクトに質問が必要です)。 finalize()はgcの直前に呼び出されるため(しかし、finalize gcが呼び出されるのは必要ですか?)または間違っているので、それはdだと思いますか?この質問に答えるには、eが必要ですか?

41
nr5

回答Eは正解です。 Eが存在しない場合、すぐにメモリ不足になります(または)正解なし。

GCに適格であるためには、オブジェクトは到達不能でなければなりません。 JVMは複数のスキャンを実行し、オブジェクトをある世代から別の世代に移動してGCの適格性を判断し、オブジェクトに到達できない場合にメモリを解放します。

53
kosa

他の回答が機能しない理由を明確にするには:

  1. System.gc()Runtime.getRuntime().gc()と共に、これはまったく同じことを行います)hintsものを破壊したい。漠然と。 JVMは、GCサイクルの必要性を認識していない場合、GCサイクルを実行する要求を無視できます。さらに、オブジェクトへの到達可能な参照をすべて無効にしない限り、GCはそれとは関係ありません。したがって、AとBはどちらも失格です。

  2. Runtime.getRuntime.gc()は文法が正しくありません。 getRuntimeは変数ではなく関数です。それを呼び出すには、括弧が必要です。したがって、Bは二重失格です。

  3. Objectにはdeleteメソッドがありません。したがって、Cは失格となります。

  4. Objectdoesにはfinalizeメソッドがありますが、何も破壊しません。 実際にオブジェクトを削除できるのはガベージコレクタだけです。(そして多くの場合、技術的にはわざわざさえしませんthat;彼らは他のことをするときそれをコピーしないので、それは取り残されます。)finalizeは、オブジェクトにクリーンアップする機会を与えるだけですbeforeJVMはそれを破棄します。さらに、finalizeを直接呼び出さないでください。 (finalizeは保護されているため、JVMは任意のオブジェクトでそれを呼び出すことを許可しません。)したがって、Dは失格となります。

  5. それに加えて、object.doAnythingAtAllEvenCommitSuicide()では、実行中のコードにobjectへの参照が必要です。それだけで「生存」し、ガベージコレクションの対象外になります。したがって、CとDは二重失格となります。

31
cHao

短い答え-E

Is Eと答えると、残りは明らかに間違っていますが、..

長い答え-それはそれほど単純ではありません。場合によります ...

単純な事実として、ガベージコレクターは、メモリの負荷が極端に高くない限り、コレクションの実行可能な候補であるすべてのオブジェクトをガベージコレクションすることは決してありません。そして、Javaは他の言語と同様にメモリリークの影響を受けやすいという事実があります。それらを引き起こします!

次の記事には、メモリ管理がどのように機能し、どのように機能しないのか、何によって何が取り上げられるのかに関する多くの詳細が記載されています。 世代別ガベージコレクターの仕組み および メモリのおかげ(JVMがWindowsおよびLinuxでネイティブメモリを使用する方法を理解する)

リンクを読むと、Javaのメモリ管理は複数選択の質問ほど単純ではないという考えが得られると思います。 。

17
user177800

Nullに設定します。その後、参照はなくなり、オブジェクトはガベージコレクションの対象になります。 GCはヒープからオブジェクトを自動的に削除します。

7
user1843495

コードは次のとおりです

public static void main(String argso[]) {
int big_array[] = new int[100000];

// Do some computations with big_array and get a result. 
int result = compute(big_array);

// We no longer need big_array. It will get garbage collected when there
// are no more references to it. Since big_array is a local variable,
// it refers to the array until this method returns. But this method
// doesn't return. So we've got to explicitly get rid of the reference
// ourselves, so the garbage collector knows it can reclaim the array. 
big_array = null;

// Loop forever, handling the user's input
for(;;) handle_input(result);
}
4
Mathan

Javaガベージコレクションを行う明示的な方法はありません。JVM自体は、オブジェクトにアクセスするすべての方法を意味する、参照を持たないオブジェクトをチェックするバックグラウンドでスレッドを実行します。一方、オブジェクトは、オブジェクトを作成したプログラムが終了または終了したスコープである場合、ガベージコレクションの対象にもなります。質問に答えると、finalizeメソッドはC++のデストラクタと同じです。 。finalizeメソッドは、JVMがオブジェクトメモリをクリアする直前に実際に呼び出されますが、プログラム内でfinalizeメソッドを定義するかどうかはユーザー次第ですが、プログラムの終了後にオブジェクトのガベージコレクションが行われる場合は、終了すると、JVMはプログラムで定義したfinalizeメソッドを呼び出しません。finalizeメソッドの使用方法を尋ねる場合がありますか?たとえば、外部ファイルへのストリームを必要とするオブジェクトを作成し、exこのオブジェクトに対して、ファイルに対して開かれたストリームが存在するかどうかをチェックし、存在しない場合はストリームを閉じるかどうかをチェックするfinalizeメソッドを明示的に定義します。数行のコードを書いた後、オブジェクトへの参照を失ったとします。その後、ガベージコレクションの対象となります。 JVMがオブジェクトのスペースを解放しようとするとき、JVMは、ファイナライズメソッドを定義したかどうかをチェックし、ストリームを開くリスクがないようにメソッドを呼び出します。 finalizeメソッドを使用すると、プログラムのリスクがなくなり、より堅牢になります。