ディレクトリナビゲーション
序文
パフォーマンス最適化のトピックは、次の4つの部分で構成されています。
- Tomcatのパフォーマンスの最適化
- MySqlパフォーマンスの最適化
- JVMパフォーマンスの最適化
- 性能試験
このセクションは、パフォーマンス最適化のトピックの2番目の部分です-JVMパフォーマンス最適化、合計6つのセクション、すなわち:
これらの6つのセッションを通じて、次のことを学びます。
➢JVMメモリモデルと各パーティションの詳細な説明を理解します。
➢ランタイムデータ領域、特にヒープメモリの構造と特性に精通している。
➢GCの3つの収集方法の原理と特徴に精通している。
➢GCチューニングツールを使用してオンラインの問題を迅速に診断する能力。
➢本番環境で増加したCPU負荷にどのように対処しますか?
➢実稼働環境でのアプリケーションに適したスレッドはいくつですか?
➢JVMバイトコードとは何ですか?
オブジェクトの作成
•オブジェクトへのメモリの割り当て
•スレッドセーフの問題
•オブジェクトの初期化
•構築方法の実行
オブジェクトにメモリを割り当てます
- ポインタの衝突
- 無料リスト
スレッドセーフの問題
•スレッドの同期
•ローカルスレッド割り当てバッファー(TLAB)
スレッドローカル割り当てバッファー(ローカル割り当てバッファー)
オブジェクト構造
各オブジェクトは、オブジェクトヘッダー、オブジェクトのインスタンスデータ領域、および配置パディングバイトの3つの部分で構成されています。
- ヘッダー(オブジェクトヘッダー)
オブジェクトヘッダーは、次の3つの部分で構成されます。- マークワード:オブジェクトとロックに関する情報を記録します。オブジェクトがsynchronizedキーワードによってロックされている場合、ロックを取り巻くすべての操作はMarkWordに関連します。MarkWordは通常32ビットサイズです。世代年齢、ロックフリー状態のオブジェクトのHashCode、バイアスされたロックのスレッドID、軽量ロックのスタック内のロックレコードへのポインター、重量ロックへのポインター、ロックフラグビットなどの一部のコンテンツが保存されます。 。
- クラスへのポインタ:サイズは通常32ビットで、主にクラスのデータ、つまりメソッド領域内の位置を指します。
- 配列の長さ:配列オブジェクトのみが長さを持ちます。32ビットまたは64ビットのJVMでは、長さは32ビットです。
- InstanceData
同じ幅のデータが一緒に割り当てられます(long、double)
- パディング:
8バイトの整数倍
オブジェクトの場所
•ハンドルを使用する
•ダイレクトポインタ
スタックでのエスケープ分析と割り当て
ソースコードからクラスファイルへ
ソースコード
class Person{
private String name;
private int age;
private static String address;
private final static String hobby="Programming";
public void say(){
System.out.println("person say...");
}
public int calc(int op1,int op2){
return op1+op2;
}
}
次に、Person.javaクラスをコンパイルして、Person.classバイトコードファイルを取得します。
javac Person.java
コンパイルプロセス
Person.java->字句解析器->トークンストリーム->構文解析器->構文ツリー/抽象構文木->セマンティックアナライザー->注釈抽象構文木->バイトコードジェネレーター-> Person.classファイル
クラスファイル(クラスファイル)
クラスファイルは、8ビットバイトに基づくバイナリストリームのセットです。各データ項目は、クラスファイル内に厳密な順序でコンパクトに配置され、中央に区切り文字がないため、クラスファイル全体にコンテンツがほぼ格納されます。すべてプログラム操作に必要なデータであり、ギャップはありません。
8ビットバイトを超えるデータ項目が検出されると、ビッグエンディアン方式で保存するためにいくつかの8ビットバイトに分割されます。
クラスファイルには、次の2つのデータ型しかありません。
- 符号なし番号
- テーブル
Javaファイルをクラスバイトコードファイルに逆コンパイルした後、バイトコードをJavaファイルにコンパイルするにはどうすればよいですか?
実際、jvmはそのようなことを行うのに役立ちますが、jvmはそれをどのように実装しますか?jvmを使用しない場合、このようなバイナリバイトコードファイルをどのように解読できますか?
Oracle公式サイト(オープンソースJDKのメーカー)のクラスファイルの説明
魔法(魔法の数):
The magic item supplies the magic number identifying the class file format; it has the
value 0xCAFEBABE .
バイトコードの先頭が
cafe babe
公式サイトで確認したところ、これは固定文言です。
次に、以下を確認します。
0000 0034
公式ウェブサイトのドキュメントを通じて:
minor_version、major_version
したがって、これらの2つの16進数は、JDK8のバージョンを表す10進数52に対応することがわかります。
次に、以下を見てください。
0027
公式ウェブサイトによると、constant_pool_count
は、定数プール内の27個の定数を表す10進数27に対応することを示しています。
などなど、ここでは詳しく説明しません。興味のある方は、Oracleの公式ドキュメントにあるクラスファイルの分析を参照してください。
- 魔数
マジックナンバーバージョン
JDK1.8 = 52
JDK1.8 = 51
- クラスファイルバージョン
- 定数プール:
フォーマット:
cp_info {
u1 tag;
u1 info[];
}
-
アクセスサイン
-
クラスインデックス、親クラスインデックス、インターフェイスインデックスコレクション
-
フィールドテーブルコレクション:フィールドテーブルは、インターフェイスまたはクラスで宣言された変数を記述するために使用されます
-
メソッドテーブルコレクション
-
属性テーブルコレクション
全体の構造は次のとおりです。
ClassFile {
u4 magic; // 魔法数字,表明当前文件是.class文件,固定0xCAFEBABE
u2 minor_version; // 分别为Class文件的副版本和主版本
u2 major_version;
u2 constant_pool_count; // 常量池计数
cp_info constant_pool[constant_pool_count-1]; //
u2 access_flags; // 类访问标识
u2 this_class; // 当前类
u2 super_class; // 父类
u2 interfaces_count; // 实现的接口数
u2 interfaces[interfaces_count]; // 实现接口信息
u2 fields_count; // 字段数量
field_info fields[fields_count]; // 包含的字段信息
u2 methods_count; // 方法数量
method_info methods[methods_count]; // 包含的方法信息
u2 attributes_count; // 属性数量
attribute_info attributes[attributes_count]; // 各种属性
}
javapファイルスプリッター
javap -c Person.class> Person.txt
Compiled from "Person.java"
class com.testjvm.Person {
com.testjvm.Person();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void say();
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String person say...
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
public int calc(int, int);
Code:
0: iload_1
1: iload_2
2: iadd
3: ireturn
}
最後に書く
このセクションのコードダウンロードアドレスは次のとおりです:https://github.com/harrypottry/jvmDemo
アーキテクチャに関する知識の詳細については、この一連の記事に注意してください:Javaアーキテクトの成長の道