[解決済み] System.gc()を呼び出すのはなぜ悪い習慣なのですか?
質問
後
回答
という質問
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は、必要に応じてガベージコレクションを実行することに注意してください。
関連
-
Java Exceptionが発生しました エラー解決
-
[解決済み] Javaにデストラクタはありますか?
-
xxx:jarのアーティファクトディスクリプタの読み込みに失敗した問題は解決しました。
-
[解決済み] この2回(1927年)を引き算すると、なぜおかしな結果になるのでしょうか?
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] B "の印刷が "#"の印刷より劇的に遅いのはなぜですか?
-
[解決済み] Java で、あるコンストラクタを別のコンストラクタから呼び出すにはどうすればよいですか?
-
[解決済み] リフレクションとは何か、なぜ有用なのか?
-
[解決済み】なぜJavaの+=, -=, *=, /=複合代入演算子はキャスティングを必要としないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】javaでオブジェクトを削除する?
-
エラー java.util.NoSuchElementException
-
javaの実行中に「javaの例外が発生しました」と表示された場合はどうすればよいですか?
-
ファインバグタイプ
-
jd-gui Java Exceptionが発生しました。
-
Android Studio 3.1.2 で v4, v7 パッケージが見つからない シンボル 'AppCompatActivity' を解決できない
-
プロジェクトの依存関係を解決できなかった 解決
-
java.lang.NoClassDefFoundError: org.apache.jasper.el.ELContextImpl クラスを初期化できませんでした。
-
スレッド "main" で例外発生 java.net.BindException: アドレスは既に使用中です。NET_Bind
-
[解決済み] Javaでメモリを解放する方法は?