JVMパフォーマンスの最適化(1)JVMの最初の知識

1. JVMを最適化する理由

ローカル開発環境では、JVMを最適化する必要はめったにありませんが、実稼働環境では、次の要件がある場合があります。

  • 実行中のアプリケーションが「スタック」し、ログが出力されず、プログラムが応答しない
  • サーバーのCPU負荷が突然増加する
  • マルチスレッドアプリケーションで、スレッド数を割り当てる方法は?

今回使用したJDKのバージョンは1.8です

第二に、JVMの動作パラメータ

jvmで設定できるパラメーターは多数あるため、jvmはさまざまな環境で効率的に実行でき、ほとんどのパラメーターはデフォルトで保持できます。

2.1 3つのパラメータタイプ

jvmのパラメータタイプは、次の3つのカテゴリに分類されます。

  • 標準パラメータ

    1. -助けて
    2. -バージョン
  • -Xパラメーター(非標準パラメーター)

    1. -Xint
    2. -Xcomp
  • -XXパラメーター(使用率が高い)

    1. -XX:newSize
    2. -XX:+ UseSerialGC
2.2標準パラメータ

jvmの標準パラメーターは一般に非常に安定しており、将来のJVMバージョンでは変更されません。java-helpを使用して、すべての標準パラメーターを取得できます。
[root@localhost ~]# java -help

用法: java [-options] class [args...]
           (执行类)
   或  java [-options] -jar jarfile [args...]
           (执行 jar 文件)
其中选项包括:
    -d32          使用 32 位数据模型 (如果可用)
    -d64          使用 64 位数据模型 (如果可用)
    -server       选择 "server" VM
                  默认 VM 是 server.

    -cp <目录和 zip/jar 文件的类搜索路径>
    -classpath <目录和 zip/jar 文件的类搜索路径>
                  用 ; 分隔的目录, JAR 档案
                  和 ZIP 档案列表, 用于搜索类文件。
    -D<名称>=<值>
                  设置系统属性
    -verbose:[class|gc|jni]
                  启用详细输出
    -version      输出产品版本并退出
    -version:<值>
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  需要指定的版本才能运行
    -showversion  输出产品版本并继续
    -jre-restrict-search | -no-jre-restrict-search
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  在版本搜索中包括/排除用户专用 JRE
    -? -help      输出此帮助消息
    -X            输出非标准选项的帮助
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  按指定的粒度启用断言
    -da[:<packagename>...|:<classname>]
    -disableassertions[:<packagename>...|:<classname>]
                  禁用具有指定粒度的断言
    -esa | -enablesystemassertions
                  启用系统断言
    -dsa | -disablesystemassertions
                  禁用系统断言
    -agentlib:<libname>[=<选项>]
                  加载本机代理库 <libname>, 例如 -agentlib:hprof
                  另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
    -agentpath:<pathname>[=<选项>]
                  按完整路径名加载本机代理库
    -javaagent:<jarpath>[=<选项>]
                  加载 Java 编程语言代理, 请参阅 java.lang.instrument
    -splash:<imagepath>
2.2.1実際の戦闘

1:jvmバージョンを表示する
[root@localhost ~]# java -version

java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) Server VM (build 25.201-b09, mixed mode)
[root@localhost ~]# 

2:-Dを使用してシステムプロパティパラメータを設定する

/**
 * @program: hgyq_app
        * @ClassName TestJvm
        * @description:
        * @author: lyy
        * @create: 2020-04-21 10:49
        * @Version 1.0
        **/
public class TestJvm {

    public static void main(String[] args) {
        String str = System.getProperty("str");
        if(str == null){
            System.out.println("muxiaonong");
        }else{
            System.out.println(str);
        }
    }
}

コンパイルとテスト:

# 编译
[root@localhost ~]# javac TestJvm.java 

#测试
[root@localhost ~]# java TestJvm
muxiaonong
[root@localhost ~]# java -Dstr=520 TestJvm
520
2.2.2 -serverおよび-clientパラメーター

jvmの実行パラメーターは、-serverまたは-clientで設定できます。

  • これらの違いは、サーバーVMの初期ヒープスペースが大きくなることです。デフォルトでは、パラレルガベージコレクターが使用され、低速で起動して高速で実行されます。
  • クライアントVMは比較的保守的で、初期ヒープスペースは小さくなり、シリアルガベージコレクターを使用します。その目的は、JVMをより速く起動することですが、実行速度はServermモードよりも遅くなります。
  • JVMが起動すると、ハードウェアとオペレーティングシステムに応じて、サーバーまたはクライアントJVMを自動的に使用します。
  • 32ビットオペレーティングシステム
    1. Windowsシステムの場合、ハードウェア構成に関係なく、デフォルトでクライアントタイプのJVM
    使用されます。2。別のオペレーティングシステムの場合、マシンは2GBを超えるメモリと2つを超えるCPUで構成されます。モード、それ以外の場合はクライアントモードを使用
  • 64ビットオペレーティングシステム
    1. サーバータイプのみ、クライアントタイプはサポートされていません

テスト(このマシンは32ビットオペレーティングシステムです):

# 参数操作系统位数
[root@localhost ~]# cat /proc/version
Linux version 2.6.32-358.el6.i686 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) ) #1 SMP Thu Feb 21 21:50:49 UTC 2013

#设置Jvm的运行参数
[root@localhost ~]# java -client -showversion TestJvm
[root@localhost ~]# java -server -showversion TestJvm

ここに画像の説明を挿入

2.3 -Xパラメータ

非標準的なパラメータの-X JVMパラメータは、JVMの異なるバージョンは、引数は、次のことができない可能性がありますjava -X非標準的なパラメータを参照してください

[root@localhost ~]# java -X
    -Xmixed           混合模式执行 (默认)
    -Xint             仅解释模式执行
    -Xbootclasspath:<用 ; 分隔的目录和 zip/jar 文件>
                      设置搜索路径以引导类和资源
    -Xbootclasspath/a:<用 ; 分隔的目录和 zip/jar 文件>
                      附加在引导类路径末尾
    -Xbootclasspath/p:<用 ; 分隔的目录和 zip/jar 文件>
                      置于引导类路径之前
    -Xdiag            显示附加诊断消息
    -Xnoclassgc       禁用类垃圾收集
    -Xincgc           启用增量垃圾收集
    -Xloggc:<file>    将 GC 状态记录在文件中 (带时间戳)
    -Xbatch           禁用后台编译
    -Xms<size>        设置初始 Java 堆大小
    -Xmx<size>        设置最大 Java 堆大小
    -Xss<size>        设置 Java 线程堆栈大小
    -Xprof            输出 cpu 配置文件数据
    -Xfuture          启用最严格的检查, 预期将来的默认值
    -Xrs              减少 Java/VM 对操作系统信号的使用 (请参阅文档)
    -Xcheck:jni       对 JNI 函数执行其他检查
    -Xshare:off       不尝试使用共享类数据
    -Xshare:auto      在可能的情况下使用共享类数据 (默认)
    -Xshare:on        要求使用共享类数据, 否则将失败。
    -XshowSettings    显示所有设置并继续
    -XshowSettings:all
                      显示所有设置并继续
    -XshowSettings:vm 显示所有与 vm 相关的设置并继续
    -XshowSettings:properties
                      显示所有属性设置并继续
    -XshowSettings:locale
                      显示所有与区域设置相关的设置并继续

-X 选项是非标准选项, 如有更改, 恕不另行通知。
2.3.1 -Xint、-Xcomp、-Xmixed
  • インタープリターモードでは、-XintタグはすべてのバイトコードをJVMに実行させますが、実行速度は通常10倍以上低下します

  • -Xcompパラメータ-Xintはそれと正反対です)。JVMを初めて使用するときは、すべてのバイトコードをローカルコードにコンパイルして、最大限の最適化を実現します

    1. 使用中のアプリケーションの多くは、-Xcompしかしよりも、パフォーマンスの若干の損失があるだろう-Xint少ない損失に起因して-Xcomp、JITコンパイラは、すべてのコードは、その後、コンパイルされた場合に判断を下すコンパイルする必要があり、JVMの全機能がJITコンパイラを起動させません一度だけ実行されるいくつかのコードには意味がありません
  • -Xmixedこれは混合モードであり、jvmによって決定される解釈モードとコンパイルモードが混合して使用されます。これは、jvmのデフォルトモードであり、推奨モードです。

例:動作モードを強く設定する

# 强制设置为解释模式
[root@localhost ~]# java -showversion -Xint TestJvm

# 强制设置为编译模式
# 注意:在编译模式下,第一次执行会比
[root@localhost ~]# java -showversion -Xcomp TestJvm

# 默认的混合模式
[root@localhost ~]# java -showversion -Xmixed TestJvm

ここに画像の説明を挿入

2.4 -XXパラメータ

-XXパラメータも非標準のパラメータであり、主にjvmのチューニングおよびデバッグ操作に
使用されます。-XX パラメータは2つの方法で使用されます。1つはブール型、もう1つは非ブール型です。

  • ブール型

    1. 形式:属性を-XX:[+-] <name>有効または無効にするマーク<name>、+は開く、-は閉じるを意味する
    2. 例:-XX:+ DisableExplicitGCは、gc操作の手動呼び出しを無効にすることを意味します。これは、System.gc()の呼び出しが無効であることを意味します
  • 非ブール型

    1. フォーマット:-XX:<name>=<value>示し<name>た属性の値を<value>
    2. 例:-XX:NewRatio = 1は新世代と旧世代の比率を意味します
  • GCコレクションの詳細を印刷するかどうか

    1. -XX:+ PrintGCDetails
    2. -XX:-PrintGCDetails
  • シリアルガベージコレクターを使用するかどうか

    1. -XX:+ UseSerialGC
    2. -XX:-UserSerialGC

ここで-XX:属性値を構成した後ここに画像の説明を挿入
、メインメソッドを開始します。
ここに画像の説明を挿入

2.5 -Xmsおよび-Xmxパラメーター

-Xmsと-Xmxは、jvmのヒープメモリの初期サイズと最大サイズをそれぞれ
設定します-Xmx2048m:-XX:MaxHeapSizeと同等、JVM最大ヒープメモリを2048Mに
設定-Xms512m:-XX:InitialHeapSizeと同等、JVM初期を設定ヒープメモリは512M
です。JVMのメモリサイズを適切に調整すると、サーバーリソースを最大限に活用してプログラムをより高速に実行できます。
例:

[root@localhost ~]# java -Xms512m -Xmx2048m TestJvm
muxiaonong
2.6 jvmの実行パラメータを表示する

jvmの実行中のパラメーターを確認する必要がある場合があります。この要件には2つの状況があります。1つ目は、
javaコマンドの実行時に実行中のパラメーターを出力すること、
2つ目は、実行中のjavaプロセスのパラメーターを表示すること、

2.6.1 javaコマンドの実行時にパラメーターを出力する
java -XX:+PrintFlagsFinal -version
ここに画像の説明を挿入

上記情報に見られるように、ブールパラメータ及び数値型は、オペレータが値である=か、:=デフォルト値を表す値と修飾は

3、JVMメモリモデル

jvmのメモリモデルは1.7と1.8の間で大きな違いがあります。この記事では1.8を例として使用していますが、1.7のメモリモデルについても理解します。それでは、1.7を学習する1.8のメモリモデルを最初に理解しましょう

3.1、jdk1.7ヒープメモリモデル

ここに画像の説明を挿入

  • ヤング領域(世代)
    ヤング領域は、エデン領域と2つのサバイバー領域がまったく同じサイズの3つの部分に分かれています。サバイバー領域は、一度に1つだけ使用され、もう1つはガベージコレクション用に予約されています。オブジェクトをコピーする場合、Eden間隔がいっぱいになると、GCは残っているオブジェクトを空きSurvivor間隔に移動します。JVMの戦略によると、いくつかのガベージコレクションの後、Survivorでまだ残っているオブジェクトは、保有期間。

  • Tenured
    Tenured領域では、主にライフサイクルの長いオブジェクト(通常は古いオブジェクト)が保存されます。一部のオブジェクトがYoungによって特定の回数コピーおよび転送されると、オブジェクトはTenured領域に転送されます。通常、アプリケーションレベルがシステムで使用されている場合キャッシュ、キャッシュ内のオブジェクトはこの間隔に転送されることが多い

  • 永久ペルミ地方
    パーマMAINは保存class、method、filed对象時々遭遇したときに、このスペースは、アプリケーションサーバの熱い展開に使い捨てローディングクラスの多くない限り、しかしデザインで、一般的にオーバーフローの一部ではありません、java.lang.OutOfMempryError:PermGen Spaceこのエラーの原因となったバグを大きな理由は、毎回再デプロイされる可能性がありますが、再デプロイ後にクラスクラスがアンインストールされないため、多数のクラスオブジェクトがpermに保存されるためです。この場合、通常はアプリケーションサーバーを再起動します。問題を解決する

  • 仮想領域
    最大メモリと初期メモリの違いは仮想領域です

3.2、jdk1.8ヒープメモリモデル

ここに画像の説明を挿入

上図からわかるように、jdk1.8のメモリモデルは、若い世代+古い世代
若い世代:Eden + 2 の2つの部分で構成されています。サバイバーの
古い世代:jdk1.8
で最も変化が大きいPerm領域のOldGenを使用します。メタスペース(メタデータスペース)の交換には特別な説明が必要です。メタスペース
が占めるメモリスペースは仮想マシン内ではなく、ローカルメモリスペース内にあります。これも、1.7の永続的な世代との最大の違いです。

ここに画像の説明を挿入

3.3 1.7の常設エリアを破棄する必要があるのはなぜですか?

1.7の永久領域が放棄された理由については、公式Webサイト(http://openjdk.java.net/jeps/122)で説明を確認できます。

これは、JRockitとHotspotのコンバージェンス作業の一部です。JRockitのお客様は永続的な世代を構成する必要がなく(JRockitには永続的な世代がないため)、永続的な世代を構成しないことに慣れています。

#永続的な世代を削除することは、Hot Spot JVmとJRockit VMを統合するための取り組みです。Jrockitには永続的な世代がなく、永続的な世代を構成する必要がないためです。

実際の使用では、永続的なメモリの生成が十分でないか、メモリリークが発生して例外が報告されることが多いため、永続的java.lang.OutOfMempryError:PermGenな領域は破棄され、ローカルメモリ空間を使用する代わりにメタ空間が使用されます。

3.4。jstatコマンドを使用してヒープメモリ使用量を表示する

jstatコマンドは、ヒープメモリのさまざまな部分の使用状況とロードされたクラスの数を表示できます。コマンドの形式は次のとおりです。
jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]

3.4.1クラスローディング統計の表示
[root@localhost ~]# jstat -class 20736
ここに画像の説明を挿入
説明:

方法 説明文
ロードされた ロードされたクラスの数
バイト 占有スペース
降ろす 荷降ろし量
バイト スペースがロードされていません
時間 時間

3.4.2コンパイル統計の表示

[root@localhost ~]# jstat -compiler 20736
ここに画像の説明を挿入

方法 説明文
編集済み コンパイル数
失敗した 失敗の数
無効 利用できない数量
時間 時間
FailedType 障害のタイプ
FailedMethod 失敗した方法

3.4.3ガベージコレクションの統計
[root@localhost ~]# jstat -gc 20736

ここに画像の説明を挿入
S0C:最初のサバイバー領域のサイズ(KB)
S1C:2番目のサバイバー領域
サイズ(KB)S0U:最初のサバイバー領域のサイズ(KB)S1U:
2番目のサバイバー領域のサイズ(KB)
EC:エデン領域サイズ(KB)
EU:エデン領域サイズ(KB)
OC:古い領域サイズ(KB)
OU:古い領域サイズ(KB)
MC:メソッド領域サイズ(KB)
MU:メソッド領域サイズ(KB)
CCSC:圧縮クラススペースサイズ(KB)
CCSU:圧縮クラススペース使用サイズ(KB)
YGC:若い世代のガベージコレクション時間
YGCT:若い世代のガベージコレクション時間
FGC:古い世代のガベージコレクション時間
FGCT:古い世代のガベージコレクション時間経過時間
GCT:ガベージコレクションによって消費された合計時間

4.まとめ

記事はここで終了します。疑わしい兄弟は、以下でメッセージを議論したりメッセージを残したりできます。また、皆さんに幸せな年を、健康で健康に、そして良い仕事をしたいと思います。さあ、私は小さな農家です!

62件の元の記事を公開 称賛された478 200,000回

おすすめ

転載: blog.csdn.net/qq_14996421/article/details/105651927