質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
JVM

JVM(Java Virtual Machine)があれば、一連のコンピューターソフトウェアプログラムとデータストラクチャが、仮想マシンモデルを使って他のコンピュータプログラムやスクリプトを拡張できます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

2回答

4011閲覧

JavaのGCが呼び出されるタイミングについて

Pizzaking

総合スコア42

JVM

JVM(Java Virtual Machine)があれば、一連のコンピューターソフトウェアプログラムとデータストラクチャが、仮想マシンモデルを使って他のコンピュータプログラムやスクリプトを拡張できます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

2クリップ

投稿2020/09/01 08:24

編集2020/09/02 07:11

先日JavaのGCについて調べたのですが、3つ気になることが出てきたので、質問をします。

  1. JavaのGCはなぜプログラマーが直接呼び出せないのですか?(System.gc()で提案はできるが、すぐにGCが実行されないのはなぜか?)
  2. JavaのGCは具体的にいつ呼び出されるのですか?
  3. GCは便利な機能ですが、

なぜobjectの破棄をプログラマーが直接できない仕様になっているのですか?

質問に間違っている点などがあったらご指摘いただけると嬉しいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

  1. GCのアルゴリズムの選択肢に委ねられているためですが、なぜ委ねられているのかが疑問かと思います。

原始的なマークアンドスイープ方式のGCであれば「GCを実行する」というのは単一のタスクとしてイメージしやすいのですが、コンカレントコレクタなどとなると、アプリケーションの実行停止を最小限に抑えるためにアルゴリズムが工夫されており、アプリケーションとGCが並行して走ったりするわけですね。

参考) https://www.jtp.co.jp/techport/2017-01-25-001/

このように並行してGCが走っている際に System.gc()が呼ばれたとしても「今、すでに走ってるから」となるわけで、今のGCが終わってから再度スケジューリングするのか、それともすでに走っているのだから無視するのか、といった選択肢が出てくるわけです。

  1. 現代的な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

  1. あるオブジェクト X をあなたがもう使わないというつもりで破棄フラグを立てれたとしましょう。

しかし、他のオブジェクトからはオブジェクト X がまだ参照されています。何も知らない別スレッドからこのオブジェクト X が利用されたときに何が起こるべきなのでしょうか?

それとも、あるオブジェクト X を破棄するぞ、と決めた段階で、オブジェクト X への参照はすべてnullに置き換えられることが望ましいのでしょうか?
別スレッドでさっきまで参照していたオブジェクト X が急に null になって NullPointerExceptionを発生させる?

JavaのGCは参照が用いられなくなったことをGCが確認できてからオブジェクトを破棄する方式をとっています。これだと誤って破棄済みのオブジェクトをプログラマが触ることはありません。
その代わり、他のスレッド含めて参照がされなくなるタイミングまでオブジェクトの破棄ができませんから、明示的にオブジェクトの破棄を宣言することはできません。

明示的に破棄ができる方式だと、別スレッド主観でまだ使っている最中なのに突然にオブジェクトが破棄されてしまうという不整合が生じてしまいます。この方式だとマルチスレッドで気軽にオブジェクトを渡すようなプログラムを書くことはできませんよね。

方式によって一長一短あり、Javaでは破棄の自由を失う代わりに、破棄済みのオブジェクトを参照してしまう問題を考えなくてよくなっているというわけです。(メモリリークは別の問題として残りますが)

投稿2020/09/08 01:13

編集2020/09/08 01:14
nagise

総合スコア87

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

JavaのGCはなぜプログラマーが直接呼び出せないのですか?

System.gc()のように提案をすることは可能です。

JavaのGCは具体的にいつ呼び出されるのですか?

メモリがなくなった時、あるいは処理に余裕があるときです。具体的なタイミングは仮想マシンの設定にもよります。

投稿2020/09/01 08:31

maisumakun

総合スコア145930

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Pizzaking

2020/09/02 07:10

System.gc()で提案ができることができるのは知っていたのですが、 なぜ、System.gc()を実行したらすぐにGCが行われないのですか?
shiketa

2020/09/08 03:58

乗合バスに乗っていて、停車ボタンを押したからといって、その場でバスが停車しないようなものだと思えばどすかね。停車の要求は受けつけるが、然るべきタイミングはおまかせ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問