JVM仮想マシンの学習ノートの詳細な理解
JVMを2回読んだ後、多くの場所がまだ理解しているようです
本のいくつかの記事を組み合わせて再編成する
jvmの本を深く理解することは良いことですが、彼の限界があるように感じます。
コアを整理する
話は混沌としていて意味がありません。
jdk 1.7と1.8の違いは依然として非常に大きいです。
一般的なプレビュー
1.クラスローディングメカニズム
クラスローディングのメカニズムは常に不明確で、テストクラスのローディングのようなインタビューの質問がたくさんあります
5プロセス
-
読み込み中
- クラスをロードするには、最初に完全修飾名でこのクラスのバイナリバイトストリームを見つけます
- バイトストリームの静的構造をメソッド領域のランタイム構造に変換します。
- メソッドエリアアクセスへのエントリとしてメモリにクラスオブジェクトを生成します。たとえば、リフレクションにはクラスオブジェクトが必要です。
-
確認する
を含む合理性を検証することです
ファイル形式、バージョン番号など
メタデータ、Java言語仕様に準拠していないものはありますか
バイトコード、いくつかの変換問題を確実にするために、指示は正しいです
-
準備ができて
静的メンバー変数の値をデフォルト値に初期化します
-
解析中
シンボル参照は直接参照になります。簡単に言えば、ポインタです
-
クラスとインターフェースの解決
カテゴリーCの分析、2つのケースに分けられます
1.Cは配列型ではなく、親クラスとインターフェースをロードする必要があるかもしれません
2.Cは配列型で、要素はオブジェクトです。最初にIntegerなどのオブジェクトをロードします
-
クラスメソッド分析
1.名前を直接確認し、参照に戻ります
2.親クラスでチェックされていません
3.抽象クラスがある場合は、インターフェースと親インターフェースをチェックインします。
-
-
初期化
メンバー変数と静的コードブロックを初期化する
JAVAプログラミングのアイデアの知識を組み合わせる
実行の順序は
親クラスの初期化>子クラスの初期化
静的変数静的コードブロック(同じレベルの記述順序を参照)初期化>共通メンバー変数(コードブロック)>コンストラクター
コードを見てください
package test; public class Father { //------- 这两个顺序只和书写顺序有关 private static String staticfiled = getStaticfiled(); static { System.out.println("父类->静态代码块"); } // ------- private String field =getNormalfiled(); public String getNormalfiled(){ System.out.println("父类->普通成员变量初始化"); return "hah"; } public static String getStaticfiled(){ System.out.println("父类->静态成员变量初始化"); return "haha"; } // 普通方法块 { System.out.println("父类->普通方法块"); } public Father(){ System.out.println("父类->构造函数"); } }
package test; public class Son extends Father { //------- 这两个顺序只和书写顺序有关 private static String staticfiled = getStaticfiled(); static { System.out.println("子类->静态代码块"); } // ------- private String field =getNormalfiled(); @Override public String getNormalfiled(){ System.out.println("子类->普通成员变量初始化"); return "hah"; } public static String getStaticfiled(){ System.out.println("子类->静态成员变量初始化"); return "haha"; } // 普通方法块 { System.out.println("子类->普通方法块"); } public Son(){ System.out.println("子类->构造函数"); } // 在子类中main函数 是仅此慢于静态代码块和静态变量 public static void main(String[] args) { System.out.println("在子类中的main主函数"); Son son = new Son(); } }
結果のグラフを見てください。
順序を決定します。
2.クラスローダー
2つのクラスが同じであるかどうかの区別は、クラスローダーが同じであるかどうか、およびクラスローダーによって異なります
親委任モデル
親の委任モデルはそのような構造です
両親は継承されずに結合されているため、親ではないと言われています。
クラスローダーはクラスをロードするリクエストを受け取り、
まず、親クラスローダーにロードを試みさせます。
親クラスローダーはリクエストを受け取り、それを子クラスローダーに引き渡すことができません
これはDNSアドレッシングの逆です。DNSがIPを見つけることができない場合、ルートDNSサーバーに引き渡されます。
違いは、ローダーの親クラスがサブクラスで機能しないことです。
DNSローカルDNSサーバーをルートDNSに引き渡すことができません
これは、オブジェクトがすべてのクラスの親クラスである理由でもあります
ロードされたクラスはキャッシュされ、次回ロードして使用する必要がないことに注意してください。
3. JVMランタイムのメモリ構造
JVMランタイムメモリ構造とJMM(JAVAメモリモデル)の違い
JVMランタイムメモリ構造はJVMにあり、JAVAメモリモデルはマルチスレッドメモリ共有の関係を研究するためのものです
ここでは、JVMランタイムメモリ構造について説明します。
文字列定数プールと参照質問をテストするような文字列インタビューの質問
いくつかの古典的なインタビューの質問
-
String str = new String( "11")はいくつかの文字列を作成しました
1つまたは2つの文字列を作成します。文字列定数プールにこのオブジェクトがある場合は、ヒープに1つだけ作成します
それ以外の場合は、ヒープに1つ、文字列定数プールに1つ作成します。
-
文字列のintern()メソッドは、定数プール内の文字列を返します。定数プールが存在しない場合は、定数プールに参加して返します
4.オブジェクトのメモリ割り当てとガベージコレクション
ガベージコレクションは主にヒープヒープ内のオブジェクトをリサイクルすることです
オブジェクトメモリの割り当てもヒープヒープに割り当てられます
リサイクルエデンエリアのオブジェクトはMinorGCです
古い世代のリサイクルはFullGCです
オブジェクトが死んでいるか、リサイクルする必要があるかを判断する方法
-
1.参照カウント方法
参照がまだある限り、リサイクルしないでください。
-
2.到達可能性アルゴリズム
このアルゴリズムはバイナリツリーのようなもので、ルートノードGCrootから下に移動します
見つかったオブジェクトは有用で、見つからなかったオブジェクトは役に立たない
GCrootオブジェクトは
スタックフレームで参照されるオブジェクトは、メソッドローカル変数です。
メソッド領域の静的オブジェクト
メソッド領域定数参照オブジェクト
ガベージコレクションアルゴリズム
-
明確にする
メモリ空間の断片化を引き起こすでしょう整理するのは簡単ではありません
-
コピー(前夜の死に適用)
複数のブロックに分割し、特定のブロックを同じブロックにコピーして、クリアします
新世代で
エデンから宇宙へ、そして宇宙へ
-
マークアップ(長期間有効なオブジェクトの場合)
生きているとマークしてメモリの一端に移動する
-
世代別(通常はこれが当てはまる)
すべてのクリーンアップには、到達可能性アルゴリズムが必要です。
次に、すべてのオブジェクトへの参照が必要です。
JVMはOopMapデータ構造を使用して、オブジェクトへの参照があることを認識します
同時に、クリーンアップではすべてのスレッドを一時停止する必要があります。これにはSTW(全世界を停止)が必要です
スレッドを一時停止すると、セキュリティ上の影響が生じます。安全のため、JVMはセキュリティポイントstwにのみ存在します
完全なGCプロセス
ガベージコレクター
多くの種類のコレクターがあり、異なる世代のコレクターと古い世代のコレクターの組み合わせが必要です。
-
シリアル
新世代のコピー、旧世代のマーク圧縮のシングルスレッドシリアルリカバリはstw
-
ParNew
シリアルマルチスレッドの新生代パラレル旧世代のシリアル新生代複製、旧世代のマーク圧縮
パラメータ:
-XX:+ UseParNewGC ParNewコレクター
-XX:ParallelGCThreadsはスレッド数を制限します
-
平行
シリアルに似ており、スループットを重視
-
パラレルオールド
古い世代、マークアップを使用
-
CMS(旧世代)は応答時間に重点を置いています
4ステップの同時マークスイープ
初期マーク(CMS初期マーク)にはgwrootがオブジェクトに短時間到達できるSTWマークがあります
並行マーク(CMS並行マーク)gcrootの子ノードの検索に時間がかかる
備考(CMS備考)のSTW時間は短い
同時スイープ(CMS同時スイープ)に時間がかかる
-
G1は現在最強です(新旧も可能)
マーキング、メモリ空間の断片化なし、新世代と旧世代は必ずしもメモリ内で連続しているとは限りません
ヒープを同じサイズの領域に分割する
一時停止時間を予測できます
クリーニングプロセスはCMSに似ています
5ステップ
1.マーカーがminorGCをトリガーする
2.地域スキャン
3.ヒープ全体の同時スキャン
4. stwで再度マーク
5.同時削除にはstwがあります