エントリーから習熟までのJVM(面接の質問を含むすべてのJVM知識ポイントの非常に詳細な要約)

目次

JVMメモリ構造

スタック

ヒープ

ガベージコレクション

物体の死を判断する方法

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

ガベージコレクター

同期されたキーワード

同期原理

ロックアップグレード

バイアスロック

軽量ロック

インタビューの回答:同期ロックアップグレードのアイデア1:


JVMメモリ構造

JVMメモリ空間は、メソッド領域、ヒープ、Java仮想マシンスタック、ローカルメソッドスタック、およびプログラムカウンタの5つの部分に分かれています。

共有スレッド:メソッド領域、ヒープ

スレッドプライベート:仮想マシンスタック、ローカルメソッドスタック、プログラムカウンター

メソッド領域:定数、静的変数、クラス情報、実行時定数プール(リテラル、シンボリック参照)

ヒープは主に配列、クラスインスタンスオブジェクト、文字列定数プールなどを格納します

スタックには基本型変数、ローカル変数、オブジェクト参照(アドレス)などの変数が格納されます

ローカルメソッドを実行します(Java実装ではなく、c実装メソッド)

プログラムカウンタ:スレッドが切り替わると、実行位置が記録され、後で再実行されます。

スタックとヒープの関係は、スタックの内容がスタックされ、スタックの参照アドレスがスタックされることです

スタック

クラス内のメソッドには、スタック内にスタックフレームがあります。スタックフレームには、ローカル変数テーブル、オペランドスタック、メソッド出口、および動的リンクが含まれます。仮想マシンは、メソッドの実行後にスペースを解放します。

ローカル変数テーブル:変数を格納します

オペランドスタック:計算中に、オペランドスタックにプッシュされ、最終的にスタックの最上位から取り出されます。

メソッド終了:メソッド終了時のリターンアドレスを指定します。

ダイナミックリンク:シンボル参照の一部はクラスのロード段階で直接参照に変換され、他の部分は実行時に直接参照に変換されます。この部分はダイナミックリンクと呼ばれます。(静的分析|動的リンク)

 

スタックオーバーフロー:メソッドの再帰により、スタックオーバーフローが発生しやすくなります。再帰的であるため、メソッドは終了していません。そのため、変数は常に作成され、スタックスペースがいっぱいになり、オーバーフローが発生します。

スタックオーバーフローコード:

public class Test {
	public void test(){
		String a;
		test();
	}
	public static void main(String[] args) {
		Test t  =new Test();
		t.test();
	}
}

 

ヒープ

ヒープにはオブジェクトと配列が格納され、新しいものはすべてヒープに配置されます。
スタックとヒープの関係は、スタックの内容がスタックされ、スタックの参照アドレスがスタックされることです。
しきい値を超えるヒープは、一般的なメモリオーバーフローOutOfMemoryErrorです。
ヒープは動的に割り当てられたメモリであり、不連続なメモリ領域であり、Javaガベージコレクタによって管理されます。

public class Test {
	public static void main(String[] args) {
		List list = new ArrayList<>();
		while (true) {
			list.add(1);
		}
	}
}

スタックとヒープの関係:スタックオブジェクトの内容、スタックオブジェクトの参照アドレス。 

ガベージコレクション

物体の死を判断する方法

オブジェクトの死を判断する方法:参照カウント法と到達可能性分析法。

参照カウント方法は、カウンタ値によって制御されます。参照されると、1ずつ増加し、参照は1ずつ減少します。短所:AはBを参照し、BはAを参照し、リサイクルできません。循環参照。

到達可能性分析の方法は、GCROOTとして安定したオブジェクトを選択し、到達可能なオブジェクトを見つけて、到達できない場合はそれを再利用することです。短所:メモリの断片化が発生します。

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

ガベージコレクションアルゴリズムには、参照カウント方法、マーククリアアルゴリズム、コピーアルゴリズム、マーク圧縮(編成)アルゴリズム、インクリメンタルアルゴリズムが含まれます。

 参照カウント方法:オブジェクトが他のオブジェクトによって参照されている場合、そのカウンターは1ずつ増加し、参照は1ずつ減少し、オブジェクトのカウンター値はリサイクル時に0になります。短所:循環参照はリサイクルできない場合があります。

マーク除去アルゴリズム:ルートノードに従って到達可能なオブジェクトを検索し、到達できない場合はそれらを再利用します。短所:スペースデブリが発生します。

コピーアルゴリズム(新世代のシリアルガベージコレクターで使用):1分あたり2ブロックのスペースが再利用時に別の領域にコピーされ、この領域が削除されます。

マーク圧縮アルゴリズム(旧時代に使用):マークスイープアルゴリズムに基づいていくつかの最適化を行いました。メモリスペースで、到達可能なオブジェクトにマークを付け、それらをメモリの片側に圧縮してから、他のオブジェクトを削除して、メモリの断片化が発生しないようにします。

ガベージコレクター

並列スカベンジ  レプリケーションアルゴリズム、重要な機能は次のとおりです。システムのスループットに注意を払います。

並列OLD   はマーク圧縮アルゴリズムを使用します

CMSコレクターの   マークスイープアルゴリズムリカバリの一時停止時間は比較的短くなりますが、それに応じてスループットが犠牲になります。B/ Sアーキテクチャに適しています。

G1 コレクタ(ごみファースト)   G1コレクタは、現在、最新のガベージコレクタであるCMSコレクターと比較すると、G1コレクタが基づいている。マーク-圧縮アルゴリズム、それはメモリの断片化を生成しません。

Javaヒープ全体を、同じサイズの複数の独立したリージョン(リージョン)に分割します。リージョンセットは、若い世代と古い世代として定義されますが、物理的な障壁ではなくなりました。

 

jdk1.7デフォルトのガベージコレクタParallelScavenge(新世代)+ Parallel Old(旧世代)

jdk1.8デフォルトのガベージコレクタParallelScavenge(新世代)+ Parallel Old(旧世代)

jdk1.9デフォルトのガベージコレクターG1

同期されたキーワード

同期原理

解体てjavapを使用すると、基礎となるJVMの手順を参照することができます。1つのがありmonitorenterと2 monitorexitロックと解除がロックされている命令は、。1つの監視出口は正常で、もう1つは異常です。

ロックのアップグレードのプロセスもあります。

ロックアップグレード

オブジェクトは、オブジェクトヘッダー、インスタンス変数、パディングバイトの3つの部分に大別できます。

オブジェクトヘッダーは、MarkWordとKlass Point(型ポインター)で構成されます。KlassPointは、オブジェクトのクラスメタデータへのポインターです。MarkWordは、オブジェクト自体のランタイムデータを格納するために使用されます。

インスタンス変数は、親クラスの属性情報を含むオブジェクトの属性情報を、4バイトに従って整列して格納します。

充填文字。仮想マシンではオブジェクトバイトが8バイトの整数倍である必要があるため、この整数倍を構成するために充填文字が使用されます。

たわみロック-「軽量ロック-」重量ロック

具体的:競合が発生するたびに(単一スレッド)-「バイアスロックの導入-複数のスレッドが競合する-」軽量ロックの導入-競合するスレッドは、他に競合が​​開始される場合、スピンして待機します- -"ヘビーウェイトロックの導入---スレッドはブロックされますが、CPUはスピン操作を消費しなくなります。

 

バイアスロック

jdk1.6より前は、Synchronizedは依然として重いロックであり、パフォーマンスはあまり良くありませんでした。Hotspotは、毎回競合するスレッドがそれほど多くないことを発見したため、偏ったロックがありました。

スレッドIDは、オブジェクトヘッダーとスタックフレームのマークワードに配置されます。同じスレッドが再び入ると、同じIDであることがわかり、直接入ります。

同じスレッドが同期ブロックに入らない場合、Kclasが指すコンテンツに従って、同じスレッドが生きているかどうかを確認します。

    (1)停止すると、CASは新しいスレッドIDを再ロックして更新します。

    (2)存続する場合は、スタックフレームに移動して、ロックオブジェクトを保持する必要があるかどうかを確認します。

           (2.1)保持する必要がなくなった場合は、それを取り消して、新しいスレッドIDに再度バイアスをかけます。

             (2.2)それでもロックを保持する必要がある場合は、スレッドを一時停止し、バイアスされたロックをキャンセルして、ロックを軽量ロックにアップグレードします。

バイアスされたロックは、パラメーター構成によってキャンセルできます-XX:-UseBiasedLocking = false

軽量ロック

競合するスレッドが少なく、待機時間が長くない場合は、軽量ロックを使用して、スピンによってロックが解放されるのを待ちます。

複数の軽量ロックがあります。

   (1)スレッドの場合、2番目のスレッドが入って、ロックオブジェクトのオブジェクトヘッダーがすでに占有されていることを検出すると、スピンして待機します。待機時間が長い場合は、ヘビーウェイトロックにアップグレードされます。 。

    (2)3番目のスレッドが入って来て、別のスレッドが回転して待機していることを検出し、それもヘビーウェイトロックにアップグレードされます。

 

注:ロックをアップグレードした後は、ダウングレードすることはできません。

インタビューの回答:同期ロックアップグレードのアイデア1:

         1.これはjdk1.6以降の最適化です。Hotspotの作成者は競合するスレッドがそれほど多くない場合は常にバイアスロックにつながることを発見しました。バイアスロックはオブジェクトヘッダーの概念です。マークワードとマークワードがあります。オブジェクトヘッダーに。kclassポイント、markwordはスレッドIDおよびその他のランタイム情報を格納します。スレッドが入ると、casはスレッドIDを更新しますが、ロックは解放されず、同じスレッドが次回直接入ることができます。
        2.競合する複数のスレッドがある場合、この時点casが失敗すると、最初にオブジェクトヘッダーに移動して、それが生きているかどうかを確認し、次にスタックフレームに移動して、存続可能かどうかを確認します。にアップグレードされます。軽量ロック。

        3.軽量ロックとは、糸が回転することを意味します。回転数が増えると、重量ロックにアップグレードされます。もう1つは、より多くのスレッドが入って誰かが回転している場合、それらもヘビーウェイトロックにアップグレードされるということです。

理解力:

部分ロック:トイレに行くために並んでいる必要はありません、あなたは一人で家にいます、あなたはドアをロックする必要はありません、そしてあなたは毎回直接入って来ます。(シングルスレッド)

軽量ロック:友人が家にやって来て、友人がトイレに行きたがっています。しばらく外で待つだけで、ドアをロックする必要はありません。(スレッド数が少なく、競争が少なく、時間が短く、ブロッキングがありません)

ヘビーウェイトロック:たくさんの友達が家にやって来て、全員がトイレに駆けつけたので、ドアをロックしました。(多数のスレッドが競合してブロックします)

 

 

おすすめ

転載: blog.csdn.net/x18094/article/details/114140817