パフォーマンス最適化トピック-JVMパフォーマンス最適化-02-クラスファイルの説明

序文

パフォーマンス最適化のトピックは、次の4つの部分で構成されています。

このセクションは、パフォーマンス最適化のトピックの2番目の部分です-JVMパフォーマンス最適化、合計6つのセクション、すなわち:

  1. JVMの紹介とエントリ
  2. クラスファイルの説明
  3. バイトコード実行エンジン
  4. GCアルゴリズムとチューニング
  5. Javaメモリモデルとロックの最適化
  6. Linuxのパフォーマンスの監視と調整

これらの6つのセッションを通じて、次のことを学びます。

➢JVMメモリモデルと各パーティションの詳細な説明を理解します。
➢ランタイムデータ領域、特にヒープメモリの構造と特性に精通している。
➢GCの3つの収集方法の原理と特徴に精通している。
➢GCチューニングツールを使用してオンラインの問題を迅速に診断する能力。
➢本番環境で増加したCPU負荷にどのように対処しますか?
➢実稼働環境でのアプリケーションに適したスレッドはいくつですか?
➢JVMバイトコードとは何ですか?

オブジェクトの作成

•オブジェクトへのメモリの割り当て
•スレッドセーフの問題
•オブジェクトの初期化
•構築方法の実行
ここに画像の説明を挿入

オブジェクトにメモリを割り当てます

  • ポインタの衝突
  • 無料リスト

ポインタの衝突と無料リスト

スレッドセーフの問題

•スレッドの同期

JVMスレッド同期メカニズムの分析

•ローカルスレッド割り当てバッファー(TLAB)

スレッドローカル割り当てバッファー(ローカル割り当てバッファー)

オブジェクト構造

各オブジェクトは、オブジェクトヘッダー、オブジェクトのインスタンスデータ領域、および配置パディングバイトの3つの部分で構成されています。

  • ヘッダー(オブジェクトヘッダー)
    オブジェクトヘッダーは、次の3つの部分で構成されます。
    1. マークワード:オブジェクトとロックに関する情報を記録します。オブジェクトがsynchronizedキーワードによってロックされている場合、ロックを取り巻くすべての操作はMarkWordに関連します。MarkWordは通常32ビットサイズです。世代年齢、ロックフリー状態のオブジェクトのHashCode、バイアスされたロックのスレッドID、軽量ロックのスタック内のロックレコードへのポインター、重量ロックへのポインター、ロックフラグビットなどの一部のコンテンツが保存されます。 。
    2. クラスへのポインタ:サイズは通常32ビットで、主にクラスのデータ、つまりメソッド領域内の位置を指します。
    3. 配列の長さ:配列オブジェクトのみが長さを持ちます。32ビットまたは64ビットのJVMでは、長さは32ビットです。
  • InstanceData

    同じ幅のデータが一緒に割り当てられます(long、double)

  • パディング:

    8バイトの整数倍

ここに画像の説明を挿入

オブジェクトの場所

•ハンドルを使用する
•ダイレクトポインタ

JVM内のオブジェクトの場所にアクセスする

スタックでのエスケープ分析と割り当て

スタック上のエスケープ分析と割り当て

ソースコードからクラスファイルへ

ソースコード

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アーキテクト成長の道

おすすめ

転載: blog.csdn.net/qq_34361283/article/details/111088549
おすすめ