JavaRush /Java Blog /Random-JA /Java のガベージ コレクターの詳細

Java のガベージ コレクターの詳細

Random-JA グループに公開済み
こんにちは!前回の講義では、Java 言語の組み込みメカニズムであるガベージ コレクターについて初めて学びました。プログラムの実行中にバックグラウンドで動作し、不要になったオブジェクトを収集します。オブジェクトは後で削除されます。これにより、将来新しいオブジェクトを作成するためにメモリが解放されます。この講義では、その動作原理を詳しく見ていきます。たとえば、オブジェクトはどの時点でどのように不要になるのでしょうか? そして、ガベージコレクターはどのようにしてこのことを知るのでしょうか? これらの質問に答えます :) 私たちの講義は概要を説明するものであり、この内容を暗記する必要はありません。メモリとガベージ コレクターの働きに関する視野を広げることを目的としているので、これを読んで自分にとって何か新しいことを学ぶだけで十分です :) さあ、行きましょう! 最初に覚えておく必要があるのは、ガベージ コレクターがプログラムと並行して実行されるということです。それはその一部ではなく、個別に機能します。これを説明するために、前回の講義ではロボット掃除機に例えました。実際、常にそうであったわけではありません。以前は、ガベージ コレクターはプログラムと同じスレッドで動作するように設計されていました。そして、あるスケジュールに従って、数分に一度、プログラム内に不要なオブジェクトが存在するかどうかをチェックし始めました。問題は、このチェックとガベージ コレクション中にプログラムがフリーズして実行されなかったことです。あなたがオフィスに座って仕事をしていると想像してください。しかし、その後、掃除婦が来て、部屋の床を洗う必要があります。彼女はあなたを 5 分間コンピューターの後ろから追い出し、あなたは彼女が掃除を終えるまで待ちます。この間は仕事をすることはできません。これは、ガベージ コレクターがかつてどのように動作していたかを大まかに説明したものです :) その後、このメカニズムが変更され、プログラム自体の動作を遅くすることなく、ガベージ コレクターがバックグラウンドで動作するようになりました。オブジェクトへの参照がなくなるとオブジェクトが消滅することはすでにご存知でしょう。ただし、ガベージ コレクターは実際には への参照をカウントしません。まず、かなり長くなる可能性があります。第二に、あまり効果的ではありません。結局のところ、オブジェクトは相互に参照できます。 ガベージ コレクターの詳細 - 2この図は、3 つのオブジェクトが相互に参照しているが、他のオブジェクトは参照していない例を示しています。つまり、プログラムの残りの部分が動作するためには必要ありません。ガベージ コレクターが単純に参照をカウントしている場合、これら 3 つのオブジェクトはすべて残り、メモリを解放しません。それらへの参照は存在します。それは宇宙船にたとえることができます。飛行中、宇宙飛行士たちは修理のためのスペアパーツのリストを確認することにし、その中に普通車のハンドルとペダルを見つけた。これらは明らかにここでは必要なく、余分なスペースを占有します。これらの部品は接続されており、いくつかの機能を持っていますが、宇宙船の運用の枠組みの中では不要なゴミであり、取り除いた方がよいでしょう。したがって、Java は、参照をカウントするのではなく、オブジェクトを到達可能到達不能の2 つのタイプに分けるガベージ コレクションの基礎を作ることにしました。。オブジェクトが到達可能かどうかを判断するにはどうすればよいでしょうか? 独創的なものはすべてシンプルです。オブジェクトは、別の到達可能なオブジェクトによって参照されている場合に到達可能です。これにより、「到達可能性の連鎖」が生じます。これはプログラムの開始時に開始され、その動作期間全体を通じて継続されます。次のようになります。 ガベージ コレクターの詳細 - 4図内の矢印は、プログラムの実行コードを示します。コードでは、たとえば main() メソッドで、オブジェクトへの参照が作成されます。これらのオブジェクトは新しいオブジェクトを参照したり、他のオブジェクトを参照したりすることができます。オブジェクトリンクのチェーンが形成されます。このリンクのチェーンを通じて「ルート リンク」、つまり実行コードで直接作成されるオブジェクトに到達できる場合、そのオブジェクトは到達可能であるとみなされます。私たちの写真では、それらは青で示されています。ただし、オブジェクトがこのチェーンから外れた場合、つまり、現在実行されているコード内のどの変数にもそのオブジェクトへの参照が含まれておらず、「リンクのチェーン」を通じてそのオブジェクトに到達することも不可能な場合、そのオブジェクトは到達不能とみなされます。私たちのプログラムでは、そのような 2 つのオブジェクトが赤で示されています。注意: これらの「赤い」オブジェクトは相互にリンクしています。ただし、前に述べたように、Java の最新のガベージ コレクターは参照カウントを行いません。これにより、オブジェクトが到達可能か到達不能かが決まります。したがって、写真にある2つの赤い物体が彼の獲物になります。ここで、プロセス全体を最初から最後まで見てみましょう。同時に、Java でメモリがどのように機能するかを見てみましょう :) Java のすべてのオブジェクトは、ヒープと呼ばれる特別なメモリ領域に格納されます。通常の言葉で言うと、「ヒープ」とは、すべてがごちゃ混ぜに置かれているオブジェクトの山のことです。しかし、Java のヒープはそうではありません。非常に論理的で合理的な構造になっています。ある晴れた日、Java プログラマは、プログラム内のすべてのオブジェクトが 2 つのタイプに分類できることを発見しました。相対的に言えば、単純なオブジェクト「長命の」オブジェクトです。「長命」オブジェクトとは、多くのガベージ コレクションを経ても生き残ったオブジェクトのことです。ほとんどの場合、それらはプログラムの終了まで存在します。その結果、作成されたすべてのオブジェクトが保存される共通ヒープは、いくつかの部分に分割されました。最初の部分には美しい名前が付いています -エデン(聖書の「エデンの園」)。これは、オブジェクトが作成された後に移動する場所であるため、素晴らしい名前です。書き込むときに新しいオブジェクトにメモリが割り当てられるのはこの部分です。new。多くのオブジェクトを作成でき、この領域のスペースがなくなると、最初の「高速」ガベージ コレクションが開始されます。ガベージ コレクターは非常に賢く、ヒープ内にさらにあるもの (ガベージ オブジェクトか作業オブジェクト) に応じて作業アルゴリズムを選択すると言わなければなりません。ほとんどすべてのオブジェクトがガベージである場合、コレクターは「ライブ」オブジェクトをマークして別のメモリ領域に移動し、その後現在の領域が完全にクリーンアップされます。ゴミが少なく、その大部分が生き物で占められている場合は、ゴミにマークを付けて掃除し、残った物を整理します。「コレクターは「生きている」オブジェクトにマークを付け、別の記憶場所に移動します」と言いましたが、どれでしょうか? 少なくとも 1 回のガベージ コレクションで生き残ったすべてのオブジェクトが転送されるメモリ領域は、生存スペースと呼ばれます。 次に、サバイバル スペースは世代に分割されます。各オブジェクトには、経験したガベージ コレクションの数に基づいて世代が割り当てられます。1 つある場合は「第 1 世代」に属し、5 つある場合は「第 5 世代」に属します。Eden と Survival Space は一緒に、 Young Generationと呼ばれるエリアを形成します。Young Generation に加えて、ヒープにはもう 1 つのメモリ領域、Old Generation (「旧世代」) があります。これらは、多くのガベージ コレクションを経ても生き残った、非常に長命なオブジェクトです。それらを他のものとは別に保管する方が有益です。そして、旧世代エリアがいっぱいの場合のみ、つまり プログラム内に存続期間の長いオブジェクトが多すぎてメモリが不足している場合でも、完全なガベージ コレクションが実行されます。1 つのメモリ領域だけでなく、通常は Java マシンによって作成されたすべてのオブジェクトが処理されます。当然のことながら、より多くの時間とリソースが必要になります。そのため、寿命の長いものは別々に保管することが決定されました。他のエリアでスペースがなくなると、いわゆる「迅速なガベージコレクション」が実行されます。カバーするエリアは 1 つだけなので、より経済的で高速です。最終的には、100歳以上の人のためのエリアさえもすでに詰まり、全面的な清掃が行われることになる。したがって、最も「重い」ツールは、必要がなくなった場合にのみアセンブラによって使用されます。概略的には、ヒープとクリーニングの構造は次のようになります。 ガベージ コレクターの詳細 - 5
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION