先日JavaのGCについて調べたのですが、3つ気になることが出てきたので、質問をします。
- JavaのGCはなぜプログラマーが直接呼び出せないのですか?(System.gc()で提案はできるが、すぐにGCが実行されないのはなぜか?)
- JavaのGCは具体的にいつ呼び出されるのですか?
- GCは便利な機能ですが、
なぜobjectの破棄をプログラマーが直接できない仕様になっているのですか?
質問に間違っている点などがあったらご指摘いただけると嬉しいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。

回答2件
5
- GCのアルゴリズムの選択肢に委ねられているためですが、なぜ委ねられているのかが疑問かと思います。
原始的なマークアンドスイープ方式のGCであれば「GCを実行する」というのは単一のタスクとしてイメージしやすいのですが、コンカレントコレクタなどとなると、アプリケーションの実行停止を最小限に抑えるためにアルゴリズムが工夫されており、アプリケーションとGCが並行して走ったりするわけですね。
参考) https://www.jtp.co.jp/techport/2017-01-25-001/
このように並行してGCが走っている際に System.gc()が呼ばれたとしても「今、すでに走ってるから」となるわけで、今のGCが終わってから再度スケジューリングするのか、それともすでに走っているのだから無視するのか、といった選択肢が出てくるわけです。
- 現代的なGCであれば裏で並行して走っているようなイメージで良いのではないでしょうか。
GCのアルゴリズムはいろいろとあるのですが、近年のものはStop the worldを極力起こさないように工夫されていて複雑化しています。
https://blog.cybozu.io/entry/2018/05/29/080000
java コマンドで実行する際に -verbose:gc をつけるとガーベッジコレクションの動作ログが表示されるので見てみてはいかがでしょうか。
https://docs.oracle.com/javase/jp/11/tools/java.html
- あるオブジェクト X をあなたがもう使わないというつもりで破棄フラグを立てれたとしましょう。
しかし、他のオブジェクトからはオブジェクト X がまだ参照されています。何も知らない別スレッドからこのオブジェクト X が利用されたときに何が起こるべきなのでしょうか?
それとも、あるオブジェクト X を破棄するぞ、と決めた段階で、オブジェクト X への参照はすべてnullに置き換えられることが望ましいのでしょうか?
別スレッドでさっきまで参照していたオブジェクト X が急に null になって NullPointerExceptionを発生させる?
JavaのGCは参照が用いられなくなったことをGCが確認できてからオブジェクトを破棄する方式をとっています。これだと誤って破棄済みのオブジェクトをプログラマが触ることはありません。
その代わり、他のスレッド含めて参照がされなくなるタイミングまでオブジェクトの破棄ができませんから、明示的にオブジェクトの破棄を宣言することはできません。
明示的に破棄ができる方式だと、別スレッド主観でまだ使っている最中なのに突然にオブジェクトが破棄されてしまうという不整合が生じてしまいます。この方式だとマルチスレッドで気軽にオブジェクトを渡すようなプログラムを書くことはできませんよね。
方式によって一長一短あり、Javaでは破棄の自由を失う代わりに、破棄済みのオブジェクトを参照してしまう問題を考えなくてよくなっているというわけです。(メモリリークは別の問題として残りますが)
投稿2020/09/08 01:13
編集2020/09/08 01:14総合スコア87
4
JavaのGCはなぜプログラマーが直接呼び出せないのですか?
System.gc()
のように提案をすることは可能です。
JavaのGCは具体的にいつ呼び出されるのですか?
メモリがなくなった時、あるいは処理に余裕があるときです。具体的なタイミングは仮想マシンの設定にもよります。
投稿2020/09/01 08:31
総合スコア144596
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。
回答へのコメント
2020/09/08 03:58

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
同じタグがついた質問を見る
JVM(Java Virtual Machine)があれば、一連のコンピューターソフトウェアプログラムとデータストラクチャが、仮想マシンモデルを使って他のコンピュータプログラムやスクリプトを拡張できます。
Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。