ガーベージコレクションとは?

このQ&Aのポイント
  • ガーベージコレクションとは、Javaにおいて不要なインスタンスを自動的に解放する仕組みです。
  • 通常、new演算子でオブジェクトを生成すると、ガーベージコレクションによって不要なインスタンスが自動的に解放されます。
  • インスタンスを残す場合は、変数にオブジェクトを代入したり、変数のスコープを広げることでインスタンスがガーベージコレクションの対象から外れます。
回答を見る
  • ベストアンサー

ガーベージコレクション?

Javaにガーベージコレクションってあるじゃん。重要そうなのですが、私の理解はイマイチです。ガーベージコレクションって何ですか?一言で言えば、ごみインスタンスなのかな。 以下は私独学の推測 インスタンスを作るとき、new Constructor();ってやるじゃん。だけど、これだけだとガーベージコレクションになって、そのうち自動的にインスタンスが消えるのかな? インスタンスを残そうとすると、左辺が重要である。 ◯ City tokyo=new City();(左辺=右辺;の形) × new City();(右辺;の形で、左辺=を省略している) 恒久的インスタンスにしようとすると、左辺で変数のクラス型と変数名を指定して、右辺の受け皿(代入先)を用意する。City型のインスタンスを作るだけなら、左辺を省略してnew City();だけで十分。しかし、これだとガーベージコレクションになって、すぐ消える。 正しい?

  • Java
  • 回答数4
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
noname#212058
noname#212058
回答No.2

ガベージコレクションは、メモリ管理機能です。 プログラム上で使用しなくなったオブジェクト(インスタン ス)を探して、メモリ上から削除するという動作をします。 例えば、  City tokyo=new City();  tokyo = null; というコードを書いた場合、tokyo = null; の実行後は City オブジェクトは使われません(使えません)。このようなオブ ジェクトはガベージコレクションが自動的に判別してメモリ 上から削除します。 また、例えば if (hoge == 0) {  City tokyo=new City(); } というコードを書いた場合、if 文のスコープを抜けた後では City オブジェクトは使われません(使えません)。このような オブジェクトはガベージコレクションが自動的に判別してメ モリ上から削除します。 このように、スコープを外れたり参照変数に null を突っ込ま れたりして、どこからも参照されなくなった(使われなくなっ た)オブジェクトを自動的に探してメモリ上から削除する機能 がガベージコレクションです。 ※注意点として、ガベージコレクションは『オブジェクトが使  われなくなったら即消す』ということはしません。JAVA の  好きなタイミングで消します。

その他の回答 (3)

noname#208507
noname#208507
回答No.4

一言でいえば、メモリリーク防止装置。 魚の目に水見えず、人の目に空見えず、Javaプログラマの目にガーベージコレクション見えず。ガーベージコレクションの重要性を知りたければ、一旦Javaを離れてガーベージコレクションがしていることを自分でやってみるのが良いでしょう。 ちょっとC言語を勉強し、malloc()を多用するプログラムを探してきてソースを読み、正常に処理するときもエラーが起きたときも間違うことなく全てのヒープメモリをfree()するために、C言語プログラマが細心の注意を払わなければならないことが実感できると、Javaのガーベージコレクションの便利さが見えてくると思います。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.3

ちょっと違いますね。 あなたの言う「ごみインスタンス」そのものではなくって、そのごみインスタンスを消すための仕組みがガーベージコレクションです。 これにはただインスタンスを消すだけじゃなくって、あるインスタンスを消してもいいかどうかを判断する機能も含まれます。 あと、細かいことですが、 > × new City(); > これだとガーベージコレクションになって、すぐ消える。 というのも間違いでです。 あるインスタンスがどこからも参照されていない状態になったとしても、それで即時に消されるとは限りません。あくまでも消されるかもしれないインスタンスになったというだけで、いつ消されるかはガーベージコレクションの都合によります。下手をするとプログラムが終了するまで残っている可能性もあります。

  • kngj1740
  • ベストアンサー率18% (197/1052)
回答No.1

塵拾いです。不要になった細切れのエリヤをなるべく連続エリヤとして集めて再度のエリヤ要求に応えられるようにする作業。細切れの空きエリヤしかない状態で大きな連続エリヤを要求されると、それに応えるべく使用中のエリヤのデータを移動したりして大きな連続エリヤを確保しようとします。こういう事態が起こると数分間とか数十分間とかそれにかかりきりになる事も。PCなど事務用ならいいかも知れませんが、実時間制御のシステムでは使えません。飛行機なら墜落します。

関連するQ&A

  • プログラミングの右辺と左辺は英語でなんていうんです

    プログラミングの右辺と左辺は英語でなんていうんですか? 変数で右辺を左辺を代入する等

  • 素朴な疑問(=について)

    Javaの勉強を始めた初心者ですが、 よろしくお願いします。 String strAAA; strAAA = "AAA"; この場合、Stringクラスからインスタンス化した変数strAAAに 代入演算子(=)で、"AAA"を代入してますよね。 自作のクラスでも同じ事が可能なのでしょうか? 例えば、clsMyClassを定義して、 clsMyClass objMyClass; objMyClass = 50; ※コンパイルエラーになる。 多分、  strAAA = "AAA"; は、  strAAA = String("AAA"); が実行されているんだと思うんですが、 Integerクラスのインスタンスでも代入演算子で可能ですよね。 =の右辺には、なんの記述も無いのに、特殊なクラスのみ可能なのでしょうか? 自作のクラスでも可能なのでしょうか? 複数のコンストラクタを作成してテストしましたが、 成功出来ませんでした。 つたない文章ですが、お知恵を頂けたら幸いです。

  • なぜ0を代入してはいけないのでしょうか?

    家庭教師をしていて、数学の問題をやっていたときに、教えていた子に 「どうして0を代入してやってはいけないのか?」と聞かれました。 (X+Y)^3+(X-Y)^3=2X^3+6XY^2 が成り立つことを証明せよ という問題だったのですが、本来なら右辺か左辺を変形して、 左辺=右辺の形にする、という答えなんです。 確かにXかYに0を代入すればイコールが成り立つ式ではあるのですが、 どうして0を代入して右辺=左辺の形にしてはいけないのかと聞かれると なんと答えていいか分かりません。 私のこの質問もわかりにくいかと思いますが、お分かりになる方、どうぞよろしくお願いします。

  • Javaのインスタンス化の構文のイメージができない

    こんばんは。 Javaプログラマを勉強しています。 サンプルプログラムで、オブジェクトの作成時、左辺と右辺でクラス名が異なる場合、 その一文ではどういうことが行われているのかイメージができません。 そこから原点に戻って、オブジェクトを作成する時の構文の一語一語の意味が分からなくなっています。 テキストによくある簡単な例だと、 ----------------- A a = new A(); ----------------- という構文があります。 この場合は左辺のAと右辺のAが同じであるため、このような構文が普通だと思い、ずっと理解した気になっていました。 ところが、 ----------------- class A {  … } class B extends A{  … } public class Main(){ public static void main(String[] args){  A a = new B();  … } ----------------- という構文が出てきた時、 A a = new B();  で、左辺のAと右辺のBは違っても大丈夫なの?何故違うの?どういう場合にこのような構文を使うの? などの疑問が出てきて、 そもそもインスタンス化の構文 A a = new A(); のそれぞれは何を意味しているのか判らなくなり、 どこからどうやって理解していけば良いのか途方にくれています。 aはインスタンス化したオブジェクトの変数名であることは理解しています。 左辺のAと、右辺のAとnew演算子をどう理解すれば良いのか悩んでいます。 自分も何が分からないかを上手く説明できないのですが、 よろしくお願いします。

  • JSのクラスについて

    JSのクラスについて https://okwave.jp/qa/q9320085.html の続き >>> >するとCat.nameとなりCatクラスという箱の中に入っているnameプロパティ?いや引数という事なのでしょうか? 引数ではなくプロパティです、ここではクラス内部のローカル変数と説明しているモノです(初心者に分かりやすいか どうかは別としてプロパティと言った方が正確ですね)。 関数内部(関数が持っている)のローカル変数は ご存知ですか?、それに類似しています、この場合はクラス内部(クラスが持っている)のローカル変数と言うイメージです。 Cat.nameとなりCatクラスという箱の中に入っているnameプロパティなのですね。 nameとコンストラクタの引数があるのでthis.nameのnameも引数なのかと思ったのですが、ドットつながりなのでcatクラス(オブジェクト)の中にあるnameプロパティ という事ですね。 関数のスコープの中で宣言する変数のことですよね。 巻き上げが起こる変数ですね。 これとクラス内の変数はほぼ同じ挙動をするという事ですか? するとスコープがクラスにもあるのでしょうか? 巻き上げも >>> >なぜこの例えはこんなわかりにくいことをしたんですかね? 恐らく同じ名前でも「this.」が付いてるか付いてないかで区別できるので、同じ名前でもコンフリクト(衝突、競合)せずに使えると言う例を示したかったのかもしれません。 thisで別の引数?の物と区別できるという事を伝えたかったのですね。 ただ二つはコンストラクタの引数でthis.nameだけはそもそも引数ではなくプロパティなので、 仮にかぶっても問題ないのでしょうね。 >>> >変数と似ている箱で 変数と違う箱と考えて下さい。 オブジェクト、クラス、関数、変数などいろいろな箱がありこんがらがるのですが、 もしかしてこれらはすべて変数なのですか? つまり箱はすべて変数で、これらは少し個性の違う変数なのでしょうか? >>> >特殊な箱でなんでも好きに入れ替えできず、 >入れられるものと入っていなくても良いものが固定されている箱という事でしょうか? >つまり変数と違ってコンストラクタが絶対に入っている箱なのですね。 初期設定が必要ないなら、コンストラクタは必要ないようです。 クラスをインスタンス化したい場合のみコンストラクタは必要で、 インスタンス化が不要なクラスなら必要ないという事でしょうか? ただクラスはインスタンス化しないと利用できないので、 文法上はコンストラクタなしでも良いが、実際はそのようなことはあり得ないという事でよいでしょうか? またインスタンス化と初期設定の違いが判らないのですが、イコールと考えてよいでしょうか? >>> >入れられないものもあるのですか? クラス内クラスは無理なようです。 それ以外はオブジェクトのように入れられるのですね。 >>> >var コンストラクターの「name」= my cat;という事ですかね? その説明は変な感じです、実際のプロセスを考えて下さい(「my cat」ではなく"my cat"文字列です)。 new Cat("my cat") ←ここでコンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれます。 constructor(name) {this.name = name} とは constructor関数の中に中カッコ内の式があり、 catクラス内のnameプロパティにconstructorの引数nameを代入するという事ですよね。 不思議なのはconstructorの引数nameを代入する部分なのですが関数の引数を代入するというのは初めて見ました。 仮引数nameなので constructor(name) { var name = "my cat"; this.name = name } という事ですよね。 つまり下記のcatクラスの引数が実引数になるという事ですよね。 //インスタンス作成 var clsObj = new Cat("my cat"); 関数であれば関数の呼び出しにある引数が実引数として代入されますが、 クラスの場合はconstructor関数の呼び出しにある引数ではなく クラスのインスタンス化にある引数が実引数として代入されるというルールなのですね。 constructor関数の呼び出しがないのが不思議でしたが、 constructor関数は定義するだけで呼び出しはしなくても実行されて、インスタンスを作成するのですね。 そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 >>> 「インスタンスの引数」と言うのは違います。 new Cat("my cat"):Catクラスに実引数"my cat"文字列を設定しnewすると、コンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれ、インスタンスが生成されます。 こちらも上記の説明で正しいでしょうか? >>> コンストラクターが在る場合もコンストラクターは初期設定だけです。 クラス"設計図"からインスタンス"実態"を作成すると言う事で、例えるなら十徳ナイフの"設計図"から十徳ナイフの"実態"を作成すると言うイメージして下さい。 (十徳ナイフの"実態"を作成しても)十徳ナイフが置いてあるだけでは何も役に立ちません、十徳ナイフは使ってこそ役に立つ訳です、例えば十徳ナイフの「栓抜き」(機能)を使うと言うのが「栓抜き」メソッド、「缶切」(機能)を使うと言うのが「缶切」メソッドに対応すると言うイメージです。 なるほどクラスがナイフの設計図で、constructor、newクラス名がナイフを作るための作業で、 ナイフがインスタンス化されたオブジェクトですが、この時点では何のメリットもないのですね。 インスタンス化されたオブジェクトを使う作業がメソッドという事ですね。 下記例ですとnew Cat("my cat");がナイフを具現化する作業(constructorもこれに当たる?)で、 実際に使うメソッドはここにはないのですかね? class Cat { (name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat("my cat"); //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); >>> 仮引数とローカル変数(プロパティー)とは違います。 ローカル変数(プロパティー)はクラスの箱の中に定義されるモノです(添付画像参照)。 上記でも記載した、仮引数と実引数が実質var name = "my cat";というローカル関数と同じ結果になるという意味で書いたのですが、 それでも違うでしょうか? もちろん同じものではないですが、実質同じ結果にはなるのですよね。 >>> そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 下記が同じ結果になるという意味なのでしょうね。 >>> 申し訳ございません訂正です、引数を引数としか考えてませんでしたが、ローカルと言われれば確かに引数もローカル変数でした。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ちなみに(コンストラクター以外は)クラスの構造がインスタンスの構造に反映されます(添付画像参照)。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ここがよくわからないのですがconstructor(name)のnameは引数ではなくプロパティなのですか? 見た目は引数に見えますが、違いとしてはプロパティは値が入れられる箱であり、 仮引数はローカル変数名でしかなく、ローカル変数そのものではないので、箱ではなく、値を入れられないのですかね?

  • PHP5 コンストラクタや初期化の意味がわからない

    プログラミング初心者です。本を参考にしてPHPを勉強しています。 クラスの章でコンストラクタについて以下のように書かれていました。 コンストラクタはインスタンス化のタイミングで実行されるという性質上、 プロパティ(メンバ変数)やクラスで使用する各種リソースの初期化 といった処理を記述するのが一般的です。 初期化処理が不要な場合、コンストラクタは省略可能。 ここで質問です。 インスタンス化を行うのは初期化するためということでしょうか? 「~といった処理を記述するのが一般的」ということは、初期化が 本来の目的ではないという意味にもとれますがどうなんでしょうか。 また静的メソッドについては、 「インスタンス化を行わなくても利用できるメソッド」 と書かれていましたが、何がどう違うのか分かりません。 初期化とは何でしょうか?またなぜ初期化を行うのでしょうか? 静的メソッドと何が違うのでしょうか?

    • ベストアンサー
    • PHP
  • BNF(バッカス)記法について

    次のBNFで定義されるビット列Sであるものは、どれか。 <S>::=01|0<S>1 ア、000111 イ、010010 ウ、010101 エ、011111 正解:ア このように<変数>は、左辺と同じ変数を右辺で用いることが出来ます。 0<S>1を考えるには、まず<S>が使われていない「01」を代入します。 すると「0011」です。と記載されています。 自力で調べたのですが、 BNF(バッカス)記法で書かれた問題が読めません。 何故「01」を代入すると「0011」になるのでしょうか。 何故「ア」が正解になるのでしょうか。 お手数お掛けしますが、ご存知の方おられましたら、ご教授お願いします。 以上、よろしくお願い致します。

  • ご教示ください。

    ご教示ください。 javaで日付操作をやっています。 通常、クラスのインスタンスを作成する場合 クラス名 変数名 = new クラス名(); ですが、カレンダークラスを使用した際に Calender 変数名 = Calender.getInstance(); と出てきました。 Calenderクラスにある、getInstanceメソッドを呼び出していると思います。 クラスをインスタンスすることで、そのクラス内にある、メソッドやフィールドを初期値で使えて(コンストラクタがない場合)と認識しています。 インスタンスで、直接、メソッドを呼び出せる場合があるのでしょうか?

  • インスタンス化について(ポリモーフィズムについて)

    Java初心者です。 Javaの書籍で、ポリモーフィズムを説明している箇所において オブジェクトを生成する際に、以下のような書き方をしているのを見ます。 1.----- スーパークラス名 オブジェクト名 = new サブクラスのコンストラクタ名(); -------- 上記は、 何を実現する為に、左辺と右辺のクラス名とコンストラクタ名を変えているのでしょうか? (もちろん詳細は実際に書かれたメソッドや変数によると思いますが、一般的な話として。) また併せて、 2.----- サブクラス名 オブジェクト名 = new サブクラスのコンストラクタ名(); ------- と書いた時とでは、使用(アクセス)出来るメソッドや変数、 生成されたオブジェクトの中身が、どのように変わってくるのでしょうか? 2.の方法では、何が実現出来ないのでしょうか? 教えて下さい!

    • ベストアンサー
    • Java
  • 共通な実数解をもつ2つの2次方程式

    共通な実数解をもつ2つの2次方程式 x^2+kx+1=0…(1) x^2-x-k=0…(2) があるとします。kは定数です。 すると (1)-(2)=0が成り立ちますよね。 すなわち(1)=(2) (しかしこのとき(1)と(2)の式の形は違う) (1)-(2)より k=-1またはx=-1 このk=-1またはx=-1を元の2式に代入すると、2式は同じ値になって(1)-(2)=0が成り立ちます。 しかしこれじゃあ2式に代入しないと分かりません。 ところで質問の本題は 共通解の問題では k=-1またはx=-1が出て これらをそれぞれ元の(2)式に代入してみて、共通解をもつのかを確かめますね。 でもこの場合 k=-1のとき (1)=(2)は等しいから 1つの式への代入でOK。 x=-1のときも (1)=(2)より1つの式への代入でOK。 (このときk=-1またはx=-1⇒(1)=(2)を知るためには結局2式に代入しかないのですかね?) しかし k=-1またはx=-1⇔(1)-(2)=0 に疑問を感じます。 (1)-(2)=0⇒k=-1またはx=-1 これは納得できます。 でもk=-1またはx=-1⇒(1)=(2) これについて はじめに書いた (1)と(2)を辺々引いて (1)-(2)=0 (このとき右辺=0は明確。しかし左辺は式の形が違う。つまり(2)式の左辺を引いた式=0となる。このとき左辺=0とは限らない。多分。) で左辺を0にするためにはk=-1またはx=-1 (このときはじめて左辺=0が分かる) このとき(1)-(2)=0 (式の形は2式とも同じ。このとき左辺=0だから0=0) つまりk=-1またはx=-1⇒(1)=(2) (左辺=0より) kとxを出す前の(1)-(2)=0 は (1)=(2)となるが式の形が違う。 これらはどう違うのでしょうか? まあつまり f(x)=0、g(x)=0があります。 このときf(x)-g(x)=0 しかし左辺は式の形が違う。 ここで左辺を0にする値を出した。 そのときはじめて f(x)=g(x)と言えるのですか? k=-1またはx=-1⇒(1)=(2)を知りたいです。 なぜ知りたいかというと 共通解を持つか確かめるときに k=-1またはx=-1⇒(1)=(2) が言えたならば kもxも片方への代入でOKです。だってもう1つに代入してもどっちにしても同じになるから。 つまり共通解の問題のとき(1)=(2)ならば 値の代入が1つでいいので、このときのk=-1またはx=-1⇔(1)=(2)を頭に入れておきたいんです。