JAVA プログラマーにとって、3 年というのはハードルです。 3 年経っても JVM を勉強していないと、プログラマーとしては役に立たない存在になってしまいます。 JVM 分析はどうですか? JVM は Java Virtual Machine の略で、JVM 仮想マシンを指します。実際のコンピュータ上でさまざまなコンピュータの機能をシミュレートする架空のコンピュータです。 JVM の存在により、JAVA プログラマーはメモリをいつ解放するかを心配する必要がなくなり、C++ プログラマーのようにメモリの量を心配する必要もなくなります。はい、JVM 仮想マシンはこれらすべての作業を完了するのに役立ちます。それでは、JAVA の JVM についてお話ししましょう。
まず、JVM モデルを見てみましょう。以前、Baidu のドキュメントを読んだのですが、その中でメソッド領域、ヒープ、スタック、カウンターなど、いくつかの項目について言及されていました。それがなくなってしまい、とても不安だったので、JVM について詳しく理解するための本を読んで、ある程度理解することができました。 『JVM の深い理解』という本では、JVM ランタイムのデータ領域は、メソッド領域、VM スタック、ネイティブ メソッド スタック、ヒープ、プログラム カウンターなど、いくつかの異なる領域に分かれていると説明されています。以下は本からの写真です。 一つずつ説明しましょう。まず、プログラム カウンター (プログラム カウンター レジスタ) について説明します。プログラム カウンターは、実際には次の命令のアドレスを格納するために使用されます。命令を実行するときは、まず命令の位置を把握し、次に命令をレジスタに移動して命令を取得し、プログラム カウンターの格納アドレスを 1 増やしてから、ループで実行する必要があります。また、プログラムカウンタの小さなメモリ領域は「スレッド専用メモリ」となります。 なぜ非公開なのですか?書籍「徹底解説 JVM」では、仮想マシンのマルチスレッド化は、スレッドを順番に切り替えることでプロセッサの実行時間を切り替えることで実現されると述べられています。実のところ、理解するのは非常に難しいです。実際には、プロセッサは 1 つのスレッドの命令のみを同時に実行しますが、その時間は不均一になる可能性があります。最初の 1 分間はスレッド a にあり、次の 1 分間はスレッド b にある可能性があります。ただし、スイッチバックの一貫性を確保するために、各スレッドには独立したプログラム カウンターがあり、影響がないように独立して保存されます。つまり、これは「スレッドプライベートメモリ」です。 プログラム カウンターには他にもいくつかの機能があります。
これら3つの文を個別に説明しましょう。これは、Java 仮想マシンを深く理解するための原文です。最初の文は非常にわかりやすいようです。 2番目の文について話しましょう。 このカウンターはバイトコード命令のアドレスを記録しますが、ネイティブ(ネイティブメソッド)であるため、たとえば、(System.currentTimeMillis()) は C を通じて実装されており、実行されるバイトコード命令にコンパイルせずにシステムを通じて直接呼び出すことができる場合、それはプログラム カウンターと同等です。記録しない場合は、カウンターの値は空である必要があります。 3番目の文については、小さなコードをコンパイルして逆コンパイルして確認してみましょう。 実際その通りです。
上記の0、2、3、5、6、8...は命令のオフセットアドレスです。 Bipush はプッシュ命令です。テスト メソッドが実行されると、スレッドは対応するプログラム カウンターを作成し、命令アドレス 0、2、3、5、6、8... をカウンターに格納します。したがって、カウンターで変化するものはメモリのサイズではなく、オーバーフローすることはありません。 JAVA仮想マシンスタック(VMスタック)についてお話しましょう スレッドはプライベートであり、スレッドと同じライフサイクルを持ちます。この仮想マシン スタックは、JAVA メソッド実行のメモリ モデルを記述し、ローカル変数、オペランド スタック、メソッド終了などの情報を格納するために使用されます。上記の bipush は push 命令です。ここで注目すべき最も重要な点は、どのようなデータが保存されるかということです。ローカル変数には既知の基本的なデータ型が含まれており、オブジェクト参照はアドレスです。 仮想マシンの仕様には、次の 2 つの異常な状態があることも記載されています。
ネイティブ メソッド スタック: これは仮想マシン スタックと非常によく似ていますが、違いは、仮想マシン スタックは JAVA メソッドを実行するのに対し、ローカル メソッド スタックはネイティブ メソッドである点です。他に違いはなく、スローされる例外も同じです。 JAVA ヒープ (heap) については、JVM の本にも記載されています。ヒープは、JAVA 仮想マシン内でメモリが最も多く占める場所です。また、すべてのスレッドで共有されるメモリ領域でもあります。ヒープ メモリは主にオブジェクト インスタンスを格納するために使用されます。 ほぼすべてのオブジェクト インスタンスはここでメモリを割り当てます。 JAVA ヒープは、ガベージ コレクターによって管理される主要な領域です。さて、ここからが本題です。面接で最も多く聞かれるガベージコレクションの仕組みについて詳しく説明します。 メモリのリサイクルは現在、世代別アルゴリズムを使用して実行されており、ヒープ、新世代、旧世代についても同様であり、2 つのガベージ コレクション メカニズムは異なるリサイクル メカニズムを使用します。新しい世代では、ガベージ コレクションが実行されるたびに、多数のオブジェクトが消滅し、少数のオブジェクトのみが生き残ることがわかります。この場合、コピー アルゴリズムが使用され、少数の生き残ったオブジェクトをコピーするコストのみを支払うことでコレクションを完了できます。 古い世代では、オブジェクトの生存率が高く、割り当てるための余分なスペースがないため、リサイクルには「マークスイープ」または「マークコンパクト」アルゴリズムを使用する必要があります。リサイクルのメカニズムについて話すには、まずヒープ パーティションを見てみましょう (開始と終了は絶対的なものではなく、オブジェクトが配置されている場所によって異なります。GC の回数が異なれば、開始と終了もそれに応じて変わります) 仕切りが一目でわかります。アルゴリズムの実装を勉強しましょう。 マイナーGC: GC新世代、 フルGC: 旧世代GC、 新しい世代のオブジェクトの生存率は比較的低いため、通常はレプリケーション アルゴリズムが使用されます。古い世代の生存率は一般的に高く、リサイクルには「マークスイープ」または「マークコンパクト」アルゴリズムが一般的に使用されます。 それが何を意味するのか理解するのに数日かかりました。私の意見を述べて、絵を描いてみましょう。 マイナーGC: 新しいオブジェクトを作成するたびに、まずそれを新しい世代の Enden 領域に配置します。これは、最初は次のようになります。 そして、Enden が使い果たされると、リサイクルできるアイテムが残ります。 その後、生き残ったオブジェクトは Survior1 (from) にコピーされ、リサイクルされるオブジェクトはリサイクルされるのを待機します。 次に、エンデンエリアをクリアしてリサイクルします このようにして最初のGCが完了し、 Enden がいっぱいになると、GC が再度実行されます。 最初はこんな感じでした そして、EndenとSurvoir1の内容がSurviorにコピーされ、 そうなるとエンデンとサバイバーはリサイクルされる すると、Enden を通過するものは移動回数が少ないものと同等になり、Survior1 を通過するものは 2 回移動するものと同等になります。 このようにして、新しい世代の GC が 2 回実行されます。 Endenが再度使用されると、Survior2からSurvior1にコピーされます。 コレクション後、Survior1が変更されました。オブジェクト 1 は Enden から直接コピーされ、オブジェクト 2 は Enden -->Survior2 -->Survior1 からコピーされ、オブジェクト 3 は Enden -->Surivior1 -->Survior2 -->Survior1 からコピーされます。ステップごとに実行すると、新しい世代の GC になります。 この場合、なぜ古い世代がまだ存在するのでしょうか?実際、GC 実行中に一部のオブジェクトがリサイクルされなかった場合、移動回数は継続的に蓄積されます。 Surior (from) から Surior (to) への各移動は、別の移動を追加することと同じです。一定回数(デフォルトは15)に達すると、古い世代に移動されます。したがって、リサイクルされないオブジェクトはありませんが、この数は設定できます。 -XX:最大テンリングしきい値 こんな感じです 実際、上記はほんの一例です。オブジェクトが大きすぎて保存できない場合は、古い世代に直接格納されます。 長寿世代をデフォルトにしている人もいて、高齢世代に入る人もいます。 さらに、このレプリケーション アルゴリズムのガベージ コレクション メカニズムは、比較的メモリを浪費します。メモリ領域の一部がアイドル状態で動作していない場合は、その利点は明らかで、シンプルで効率的です。 上記は、GC のガベージコレクションにおける新世代コピーアルゴリズムの分析です。私たちは今、新世代のマイナー GC について多くのことを知っています。上記は個人的な見解です。絵は比較的鮮明でわかりやすいです。間違いがありましたら、同僚の方々にご指摘いただければ幸いです。 |
<<: マルチクラウドデータガバナンスをより管理しやすく一貫性のあるものにする方法
[[437979]] [51CTO.com クイック翻訳] Pod は、Kubernetes アプリ...
対象ユーザー:第一段階の対象ユーザーは主に杭州の女性と一部の男性です。 2007年、杭州の常住人口は...
2018年9月現在、中国のモバイルインターネットの月間アクティブユーザー数は11億6,700万人に達...
Baidu がアプリケーション配信ポータルを獲得するために 91 Wireless を 18 億 5...
SEO最適化に関する質問と回答はたくさんあります。以前、 「新しいサイトが含まれないのはなぜか」と「...
[[427652]]この記事はWei XinyuとGuo Yuejunが執筆したWeChatパブリッ...
raksmart サーバーはどうですか?昔ながらのアメリカのコンピュータルームである raksmar...
実は、使いやすくコスト効率に優れた香港のクラウド サーバーは比較的少ないのです。なぜそう言えるのでし...
リンクパラメータ機能同じホスト上の複数の Docker コンテナが相互に通信する必要がある場合、最初...
Docker は、最新のアプリケーション開発と展開の業界標準となっています。コンテナ化テクノロジーを...
[[203968]] VMware は、さまざまな環境で NSX ネットワーク仮想化ツールを実行でき...
来週、BlueVM は顧客を新しいハードウェアに移行する予定です。時間が近づくと、BlueVM から...
6 月の時点では、良いニュースとしては、Baidu の Web 検索品質に関するホワイト ペーパーが...
Pacificrack は昨年の立ち上げ以来、低価格戦略を採用してきました。結局のところ、それらはす...
IDC Review Network (idcps.com) は 4 月 28 日に次のように報告し...