JVM仮想マシンを理解します

JVMは何ですか

略語JVM Java仮想マシン(Java仮想マシン)で、JVMは、架空のコンピュータであるコンピューティングデバイスのための仕様は、様々なコンピュータ実現される機能の実際のコンピュータシミュレーション上を通過されます。
Java仮想マシン語を導入した後、Java言語は、ときに、異なるプラットフォーム上で実行するために再コンパイルする必要はありません。唯一のJava言語コンパイラは、オブジェクトコード(バイトコード)を生成するように、特定のシールドのプラットフォームに関連付けられているJava言語情報を使用してJava仮想マシンで実行中のJava仮想マシンは、複数のプラットフォーム上で変更することなく実行することができます。

Java仮想マシンの構造

ここに画像を挿入説明
広くオンライン流通のこのピクチャ参照JVMの構成図。

ランタイムデータ領域

プログラムの実行中にさまざまなランタイムデータ領域。Java仮想マシンが起動されたときにデータ領域の一部が作成され、破壊されたときだけのようなJava仮想マシンが終了、メソッド領域ヒープエリアのデータ領域。他の地域プライベートのスレッドは、各データ領域が破壊されたときのようなスレッドが終了、PCプログラムカウンタ仮想マシン・スタックネイティブメソッドスタック

PCプログラムカウンタ

各CPUは、プログラムカウンタPCは、多くの場合、行番号インジケータと呼ばれる、アドレスを実行し、現在のスレッドのバイトコード命令を記録し、プログラムカウンタPCすなわち登録しています。
バイトコードインタプリタ作業は、バイトコード命令は、プログラムカウンタの値を変更することにより、選択された場合、分岐、ジャンプ、ループ、例外処理と、このカウンターを達成するために必要な他の基本的な機能を実行する必要があります。
Javaは言語のサポート、マルチスレッド化され、マルチスレッド、いわゆる現実は、プロセッサ命令は、実行の一つのスレッドのみ、タイムスライス内、CPUのラウンドロビンスケジューリングアルゴリズムによって達成されます。
切替処理スレッドは、各スレッド(すなわちプライベートスレッド)別のプログラムカウンタを有することになるときに実施を確保するために、単離されたストレージ、さまざまなスレッド間で相互に害することなく、元の位置に復帰させることができる
プログラム・カウンタは、Java仮想マシンで唯一の仕様でありますこれは、メモリのオーバーフロー状態の任意の領域のために用意されていません。

Java仮想マシンのスタック

仮想マシンのスタックのJavaメモリ・モデルは、方法を説明した方法を実行するローカル変数テーブル記憶方法、オペランドスタック、出口の方法のような動的な接続情報、各メソッドのスタックフレームを作成しながら行います実行が呼び出したノウハウから完成されて、それは仮想マシンプロセススタックでスタックをプッシュするスタックフレームに対応しています。

ヒープ

各スレッド共有メモリ領域は、クラスのインスタンスとヒープ上に割り当てられたメモリのアレイは、ヒープは、ときに、仮想マシンの起動を作成します。

メソッド地区

各クラスのストレージ構造、例えば、実行時定数プール、フィールドおよびメソッド静的データについて、方法及びコンストラクタコード、クラスとインタフェースと初期化をインスタンス化するための特別な方法を含む、実行時定数プール領域割り当て方法もメモリ

ランタイム定数プール

そして、コンパイラによって生成された様々なリテラルの参照シンボルを格納するため、この部分は面積がロードされたクラスのメソッドを入力します。

ネイティブメソッドスタック

Java仮想マシンのスタック効果は、Java仮想マシンサービスメソッドのための彼らの仮想マシンの実行スタックの違いのうそ、およびネイティブメソッドスタック、ネイティブサービスのメソッドを使用するように仮想マシン似ています。仮想マシン言語仕様のネイティブメソッドスタック、およびデータ構造は必須ではない方法、それを実施することができる特定の仮想マシンの使用。直接組み合わせたネイティブメソッドスタックおよびスタックの仮想マシンにいくつかの仮想マシン。

親委譲モデル

クラスローダの負荷がクラスが要求を受信した場合は、それが自分のこのクラスをロードするためにはありませんが、完了するために、親クラスローダにこの要求を委任し、その要求は、子クラスローダを完了できなかった場合にのみ、親クラスローダがロードクラスをロードしようとします。

ここに画像を挿入説明

クラスローダ

スタートクラスローダ:ブートストラップクラスローダは、コアライブラリをロードするために使用される仮想マシンの一部です。JAVA_HOME / lib /ディレクトリ、または-Xbootclasspathパスによってパラメータで指定された仮想マシンは、ライブラリに識別された
拡張クラスローダーを:拡張クラスローダ、Java拡張ライブラリをロードする責任があります。すべてのライブラリのロード/ libに/ extディレクトリまたはシステム変数のjava.ext.dirsは、パスを指定しました。
アプリケーションクラスローダ:アプリケーションクラスローダは、ユーザーのクラスパスをクラスパスに指定されたライブラリをロードするための責任がある、私たちは、直接このクラスローダを使用することができます。通常、我々は、カスタムクラスローダーのデフォルトはローダーを使用することである必要はありません。

クラスのライフサイクル

クラスは実際には、彼の全体のライフサイクルは7段を含む、これまでのメモリをアンロードし始めた仮想マシンのメモリにロードされています。
ロード、検証、準備、解析、初期化、使用してアンインストール。
これでロード、検証、準備、初期化と解析5つの段階が連続している、と分析のかもしれないではありません。

クラスのロード

クラスはのライフサイクルの最初の5つのステージでここに画像を挿入説明
ロードする三つのことについて行われなければ、仮想マシンのニーズを
クラスから、バイナリバイトストリームを取得するために(1)(から、クラスに名前を付けることにより、取得したファイルのパーミッションを指定していません他のようなチャネル、動的に生成されたネットワーク、データベース、等)
(2)この静的記憶構造は、データ構造領域ランタイムメソッドにバイトストリームによって表される
その方法のHotSpot VM領域の目的のためにメモリ内の(3)( )このクラスの各種データ入力領域にアクセスするための方法として、このクラスの代表的なjava.lang.Classオブジェクトを生成する
検証一般に、4つの段階の動作の検査を完了するために必要とされるが
、(1)ファイル形式の検証は:バイトストリームかどうかを確認しますクラスファイル形式の仕様(バージョン番号は、プールタイプがサポートされていない一定の定数が存在するか否かを、仮想マシン処理の範囲内である)
メタデータの(2)検証:情報はに意味解析バイトコード説明しましたJavaの言語仕様の要件に記載された情報の遵守を確保する(例:もしjava.lang.Object上位を除いてそこに親クラス、); (。
3)バイトコード検証:データフローと制御フロー解析プログラムのセマンティクスを決定するが正当である、論理的、
シンボリック参照の(4)検証:分析動作を正しく行うことができることを確実にします。
検証フェーズは非常に重要であるが、必ずしもそうではない、プログラムの実行には影響を与えません。繰り返し検証した後、参照クラスは、時間に仮想マシンのクラスのロードを短縮するために、クラスの検証措置のほとんどをシャットダウンする-Xverifynoneパラメータを使用することを検討している場合。
レディ準備フェーズは、正式にメモリを割り当て、クラス変数(静的メンバ変数)の段階クラス変数の初期値を設定し、これらの変数によって使用されるメモリは、メソッド領域に配置されています。この時間は、ヒープ内のオブジェクトと一緒に割り当てられるオブジェクト・インスタンスのインスタンス変数を含まない専用メモリ割り当てクラス変数、インスタンス変数を含みます。第二に、ここでは初期値「通常」は、次のようにクラス変数が定義されていると仮定すると、ゼロ値のデータ型であります

	那么,变量在准备阶段过后的值还是0,而不是111.因为这时候没有开始执行任何Java方法,而把value赋值为
	111的putstatic指令是程序被编译后,存放于类构造器方法<clint>()之中,所以把value赋值为111的动作将在初始化阶段才会执行。
    public static int value=111;
    特殊情况:当类字段的字段属性是ConstantValue时,会在准备阶段初始化为指定值,所以标注为final之后,value在准备阶段初始值为111而不是0
    public static final int value=111;

構文解析
、構文解析段階は、仮想マシンの定数プールのプロセスを直接参照記号参照に置き換えられますです。クラスまたはインタフェース、フィールド、クラスメソッド、インターフェースメソッド、メソッドのタイプ、およびメソッド呼び出しハンドラクラスシンボルの基準点7つの修飾子にメイン分析操作。
初期化
初期化フェーズは、最終ステップクラスローディングプロセスです。外部カスタムクラスローダが、残りのアクションに参加することができ、ユーザアプリケーションのローディングフェーズにおけるJavaプログラムに加えて、クラスローディングプロセスの前に初期段階に、本格的に定義されたクラスの実装を開始し、完全に仮想マシンを支配し、制御されコード(バイトコード)。
調製システム要件一旦初期値(ゼロ値)で割り当てられているステージ変数、初期化フェーズにおいて、より露骨、主観的計画で指定された手順に従って、クラス変数やその他のリソースを初期化する、あるいはするつつ:クラスの実装の初期段階プロセスコンストラクタ()メソッド。()メソッドは割り当て操作コンパイラ自動的に収集クラス{すべてのクラス変数および静的ステートメントブロック静的ステートメント合併}によって実装され、順序コンパイラコレクションは、決定のソースファイル内のステートメントによって出現の順序でした静的ステートメントだけ前の文のブロック内で定義された静的変数へのアクセスをブロックすることができ、その背後にある変数の定義は、ブロックの前で静的ステートメントを割り当てることはできませんが、アクセスすることができます。

    int a=0;
    static {
    	a是对象创建之后才分配内存在堆上。
        a;//Non-static field 'a' cannot be referenced from a static context
    }

ここに画像を挿入説明

オブジェクトの作成

新しいコンストラクタが呼び出される使用
newInstanceメソッドを使って、クラスのコンストラクタ呼び出して
のnewInstanceメソッドコンストラクタクラスを使用して、コンストラクタを呼び出し、
cloneメソッドを使用してオブジェクト(浅いクローン、深いクローン)をクローニング
のデシリアライゼーションを使用していますか?

JVMガベージコレクションのメカニズム

Javaでは、プログラマは、表示オブジェクトのメモリを解放する必要はありませんが、仮想マシンによって自動的に実行します。JVMでは、通常の状況が実装されません下の仮想マシンがアイドル状態であるか、またはそれらへの参照がないヒープメモリの現在の不足は、スキャンの実行をトリガする場合にのみ、ガベージコレクタスレッドは、それは、低い優先度でありますこれは、オブジェクト、およびコレクションに追加は回復し、回復します

ガベージコレクションのアルゴリズム

参照カウントは、
ここに画像を挿入説明
循環参照のJVMが回収できないことがわかります。
到達可能性分析 GCルート
参照ターゲット仮想マシンスタック(テーブルのローカル変数スタックフレーム)(1)、
オブジェクト(2)メソッドゾーンクラスの静的属性参照;および
(3)オブジェクト・メソッドの定常領域が引用さ;
(4)ローカルスタック参照されるオブジェクト。ここに画像を挿入説明

復旧戦略/アルゴリズム

マーク-スイープ
なし連続したメモリ利用可能につながる、後者の必要性が大きなオブジェクトを割り当てる場合は、クリア、クリアスペースデブリの後に多くのがあるだろう、最初のマークを
マーク-仕上げ
最初のマークを、次いで透明仕上げ、解決スペースデブリ質問。そして、新たな問題が、それぞれのオブジェクトを移動しなければならなかった、ありました。
アルゴリズム複製
二つの等しい領域、一つだけを使用して、各領域に指定されたメモリ空間。現在の領域を横断するガベージコレクションは、別の領域にライブオブジェクトをコピーするために使用する場合、最後のターゲット領域のリサイクルは、現在のリサイクルを使用します。

世代コレクション
オブジェクトメモリの生存期間に基づいていくつかの部分に分割されています。一般的に若い世代を含みます。歳と永久世代、

ガベージコレクタ

Javaは、コレクタ、シリアルあり、スループットおよびユーザ応答時間優先の優先順位の種類に応じて3つの異なるシナリオを提供します
ここに画像を挿入説明

CMS(コンカレントGC)コレクタ

収集プロセスは、大きく4つのステップに分割されて全体
(1)最初のラベル
(2)同時マーク
(3)再マーク
(4)同時クリア
初期ラベルを、これら2つのステップは、ユーザが他のスレッドを一時停止し、再マークする必要があります。CMSは、マークの使用によるものである-スイープアルゴリズムすぎて、それがない割り当てるように連続したスペースを見つけることができないような大規模なオブジェクトの割り当て、メモリ空間として割り当てるオブジェクトに多くの問題をもたらすとき、それはまだ、スペースデブリの破片の多くを生成しますUseCMSCompactAtFullCollectionパラメータ:フルGCは事前に出発ではありません、この問題を解決するために、CMSコレクタは-XX提供
デフラグ処理後の再フルGCの増加のために、だけでなく、-XXを通じて:CMSFullGCBeforeCompactionパラメータが圧縮されていない多くの時間を実行するように設定されています全GC後、デフラグプロセスが続きます。

G1のコレクタ(ユーザ応答時間優先)

(1)同時並行して:
(2)世代コレクタ
(3)空間統合
(4)が失速を予測するためにここに画像を挿入説明
も存在の内部同様の市松1領域組成G1の概念
領域が導入された
同じ大きさを、値は1Mからです2バイト32Mとの間の電力停止ツリー、JVM 2048同じサイズの、左右の領域を分割しようとします。この数は、ヒープの大きさに応じて手動で調整することができ、G1は自動的に調整されます。
G1実装は、エデン領域の一部として、サバイバー、オールドの部分の一部として、G1のregion50%は、対象物の大きさが作品Humongousとして分類され、適切な領域に配置されている超えます。論理的には、このような大規模なオブジェクトをコピーするなど、古い時代の一部とみなさ作品Humongous領域は、GCの複製アルゴリズムの新世代に適した非常に高価な操作、ではありません。

欠点のG1。
領域サイズとラージオブジェクトはスペースの無駄につながることができます一貫性を確保することが困難であり、特に大きなオブジェクトは、複数の地域を占有する可能性があります。そして、地域あまりにも不適切、あなたはそれがより困難長期的存在の場合であるラージオブジェクトの配分の連続したスペースを見つけることになります。

角度GCアルゴリズム、G1の選択は次のように理解簡素化することができ、複雑なアルゴリズムである:
新世代において、G1は依然として並列アルゴリズムの使用するコピーであるので、ポーズの同じストップ世界が発生します。クリーンアップ古き良きゾーンをもたらす新世代のは、地域にマークされています。
ほとんどの場合、古い時代の下で同時マークされており、(コンパクト)が行われる仕上げとされついでにGCの新世代、そして仕上げのない整合性はなく、増分、元の領域の新世代オブジェクト際に十分に古い、旧世代領域に直接することができました。

でかいオブジェクトの割り当てと解放
古い時代の一環として、でかい領域は、通常、それは並行マークの終了後に回収されるだろうと思ったが、G1の新バージョンでは、オブジェクトでかい回復はより積極的な戦略をとっています。私たちは、古いの領域との間に記録されたオブジェクト参照のG1は、作品Humongousは、オブジェクトの数を制限することを知って、それまでの古いオブジェクト参照があるかどう素早く知ることができます。ない場合は、それへのオブジェクト参照の新しい世代がある場合、唯一の回復を防ぐことができるかもしれないが、この情報は、若いときにGCを知っているので、作品Humongousは、若いGCでないオブジェクト再利用することができます他の年に並行マークとして古いオブジェクトの待機の終わりが好き。

仮想マシンのパフォーマンス監視

VMプロセスステータスツールは-jps:仮想マシンが実行中のプロセスを一覧表示することができます。
仮想マシンの実行にメインクラス名とローカル・プロセスこれらの仮想マシン固有のIDを表示します。
-jstat監視ツール仮想マシンの統計:コマンドツールは、様々なオペレーティング・ステータス情報のための仮想マシンを監視することができます。
仮想マシンのクラスローディング、メモリ、ガベージコレクション、JITコンパイラおよびその他の営業データ表示
のJavaメモリイメージングツール-jmapを:生存ヒープ・ダンプのスナップショットのために
も、クエリの実行キューファイナライズはJavaヒープと永続的な世代を詳述することができます。
このような領域の使用状況として、集電体が使用
するJavaスタックトレースツール-jstackを:現在の時間生き残るために仮想マシンのスナップショットをスレッド
Javaが監視しすぎ-JConsole公共の管理:視覚的な監視を、管理ツールは、
メモリ、スレッドなど、JVMに関するすべての情報を、見ることができます、クラス、VMとGC要約情報

JVMのチューニングのアイデア

ビュースタック情報空間が小さすぎるヒープであるかどうかを決定する
ビューフルGC状況メモリリークがかどうかを決定するために
合理的なガベージコレクタを使用する
ヒープ領域の最小メモリと最大メモリを同一に設定されているケースの伸縮能力があるだろう

例としてJVM共通パラメータ

メモリ設定

パラメータ 意味
初期ヒープサイズ-Xms1024m
-Xmx1024m最大ヒープサイズ
-Xmn500m新生代サイズ
-Xss1024K単一スレッドスタック
-XX:PermSizeを= 200メートルの前永久Java8を置換
-XX:MaxPermSizeを= 300メートルJava8永久置換berfore
-XX:MetaSpaceSizeメタ8後
-XX:MaxMetaSpaceSizeメタデータの後8。
-XX:NewRatio 4オルデン面積比=面積ヤング4 :. 1。
-XX:= 8 SurvivorRatioエデン面積率S領域8 :. 1 :. 1。
-XX:メモリページサイズJVM LargePageSizeInBytesを最適化します国立成功大学のページングトーン

GCの設定

新生代(别名) 老年代 JVM参数
シリアル(DefNew)シリアル旧(PSOldGen)-XX:+ UseSerialGC
並列の清掃(PSYoungGen)シリアル・オールド(PSOldGen)-XX:+ UseParallelGC
並列の清掃(PSYoungGen)古い(ParOldGen)をパラレル-XX :+ UseParallelOldGC
ParNew(ParNew)シリアル・オールド(PSOldGen)-XX:-UseParNewGC
ParNew(ParNew)CMS +シリアル・オールド(PSOldGen)-XX:+ UseConcMarkSweepGCを
G1 G1 -XX:+ UseG1GC

デバッグパラメータ

パラメータ 意味 説明
-XX:+ PrintGCDetails GCログ
-XX:+ PrintGCApplicationStoppedTime GC一時停止
-verbose:gcを/クラス/ JNIビューGC、クラスのロード、ネイティブメソッド呼び出しの
-XX:GC中+ PrintHeapAtGC印刷スタックがトリガー
-Xloggcを:ログ/gc.logログ出力GC
-XX:ダンプ・ヒープメモリオーバーフロー時に+ HeapDumpOnOutOfMemoryErrorが生成
+ HeapDumpOnCtrlBreakもしくはCtrl +ブレイクはダンプを生成:-XX

公開された24元の記事 ウォンの賞賛1 ビュー531

おすすめ

転載: blog.csdn.net/qq_45366515/article/details/105045804