1. ホーム
  2. java

[解決済み] System.gc()を呼び出すのはなぜ悪い習慣なのですか?

2022-03-16 14:47:30

質問

回答 という質問 Javaでオブジェクトを強制解放する (その人は1.5GBのHashMapをクリアしていた)を使って System.gc() を呼び出すのはバッドプラクティスだと言われました。 System.gc() というコメントがありましたが、全く納得がいきません。また、私の回答にあえてupvoteやdownvoteをする人はいないようでした。

そこで「バッドプラクティスだ」と言われたのですが、「ガベージコレクタの実行でシステム的に世界が止まることはもうない」「JVMがヒントとしてのみ有効に使うこともできる」とも言われ、なんだか途方に暮れています。

JVMは通常、いつメモリを再利用する必要があるか、あなたよりもよく知っていることは理解しています。また、数キロバイトのデータについて心配するのは馬鹿げているということも理解しています。メガバイトのデータでさえ、数年前とは違っていることも理解しています。でも、それでも1.5ギガバイト?そして、あなたは 知っている メモリに1.5GBくらいのデータがぶら下がってるんだから、一発でわかるわけがないんだけどね。それは System.gc() システム的に悪いのか、それとも大丈夫になるポイントがあるのでしょうか?

だから、質問は実は二重になっているんです。

  • を呼び出すことは、なぜバッドプラクティスなのか、あるいはバッドプラクティスでないのか。 System.gc() ? それは本当にある実装の下でJVMにヒントを与えるだけなのか、それとも常に完全な収集サイクルなのでしょうか?世界を止めることなく仕事をすることができるガベージコレクタ実装が本当にあるのでしょうか?私のコメントで人々が行った様々な主張について、何らかの光を当ててください。 回答 .
  • 閾値はどこだ?それは 決して を呼び出すのは良いアイデアです。 System.gc() それとも、受け入れられる時があるのでしょうか?あるとすれば、それはどのような場合ですか?

解決方法は?

みんながいつも言っている「避けたい」理由 System.gc() であることです。 根本的に壊れているコードの良い指標 . 正しさのためにこれに依存しているコードは確実に壊れていますし、パフォーマンスのためにこれに依存しているものは、ほとんどの場合、壊れています。

どんなガベージコレクタの下で動いているのかわからない。 確かに "stop the world" が主張するように、JVMの中にはそこまで賢くないものや、様々な理由(おそらくスマホの場合?)でやらないものもあります。 何をするかわからない。

また、何かをしてくれるという保証もない。 JVMはあなたの要求を完全に無視するかもしれません。

それが何をするかわからない」「役に立つかどうかもわからない」「とにかく呼ぶべきではない」という組み合わせが、「一般的には呼ぶべきではない」と強弁される理由です。 これを使うべきかどうかを問う必要があるのなら、使うべきではない、ということなのでしょう。


EDIT 他のスレッドにあったいくつかの懸念に対応するため。

リンク先のスレッドを読んで、さらにいくつか指摘したいことがあります。 まず、ある人が gc() は、システムにメモリを戻す可能性があります。 Javaヒープ自体は、Javaの割り当てとは無関係に成長するのです。

JVMはメモリ(数十メガバイト)を保持し、必要に応じてヒープを拡張します。 Javaオブジェクトを解放しても、そのメモリをシステムに戻すとは限りません。Javaは、割り当てられたメモリを保持し、将来のJavaの割り当てに使用することはまったく自由です。

ということが可能であることを示すために System.gc() は何もしません。 JDK バグ 6668279 があること、特に -XX:DisableExplicitGC VMオプション

デフォルトでは System.gc() が有効になります ( -XX:-DisableExplicitGC ). 使用方法 -XX:+DisableExplicitGC を呼び出さないようにするには System.gc() . JVMは、必要に応じてガベージコレクションを実行することに注意してください。