JVMの詳細な記事、CMSコレクターとGCログの分析および場所の問題

ここに写真の説明を挿入
CMSコレクター戦闘

2020年に収集された第一線のインターネット企業の最新の実際のインタビューの質問(すべてドキュメントにまとめられています)、ネット、春、糸、春の雲などの詳細な説明を含む多くの乾物があり、詳細な学習計画、インタビューの質問などもあります。私はインタビューに参加していると感じていますこのセクションは非常に明確です:インタビュー情報を取得するには、ここをクリックしてください!!!パスワード:CSDNここに写真の説明を挿入

実際の戦闘が始まります、準備はいいですか?

ここに写真の説明を挿入
ここに写真の説明を挿入

シミュレートされたビジネスシナリオコード:

@RestController
public class IndexController {
    
    
/***
 * 存 big 对象
 * @return
 */
@GetMapping("/put")
public String process() {
    
    
   ArrayList<User> users = queryUsers();
   for (User user:users){
    
    
      //TODO 业务操作
   }
   return "ok";
}
private ArrayList<User> queryUsers() {
    
    
   ArrayList<User> users = new ArrayList<>();
   for (int i = 0; i < 50000; i++) {
    
    
      users.add(new User(i, "java2b"));
   }
   return users;
}
}
public class User {
    
    

   private int id;
   private String name;
   private byte[] data;

   public User(int id, String name) {
    
    
      this.id = id;
      this.name = name;
      data=new byte[1 * 128 * 1024];
   }
}

出力コレクター情報:

/***
 * 打印 jvm 信息
 * @return
 */
@GetMapping("/info")
public String info() {
    
    
   List<GarbageCollectorMXBean> garbages = ManagementFactory.getGarbageCollectorMXBeans();
   StringBuilder stringBuilder = new StringBuilder();
   for (GarbageCollectorMXBean garbage : garbages) {
    
    
      stringBuilder.append("垃圾收集器:名称=" + garbage.getName() + ",收集=" + garbage.getCollectionCount() + ",总花费时间="
              + garbage.getCollectionTime());
      // + ",内存区名称=" + Arrays.deepToString(garbage.getMemoryPoolNames()));
      stringBuilder.append("\r\n");
   }
   MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
   MemoryUsage headMemory = memory.getHeapMemoryUsage();
   long MB = 1024 * 1024;
   stringBuilder.append("head 堆:");
   stringBuilder.append("\t 初始(M):" + headMemory.getInit() / MB);
   stringBuilder.append("\t 最大(上限)(M):" + headMemory.getMax() / MB);
   stringBuilder.append("\t 当前(已使用)(M):" + headMemory.getUsed() / MB);
   stringBuilder.append("\t 提交的内存(已申请)(M):" + headMemory.getCommitted() / MB);
   stringBuilder.append("\t 使用率:" + headMemory.getUsed() * 100 / headMemory.getCommitted() + "%");
   return stringBuilder.toString();
}

サーバーの
起動パラメーターにデプロイされたjarパッケージを生成します。

 java -Xms256m -Xmx256m -verbose:gc -Xloggc:/root/jvm/gc-cms.log -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintHeapAtGC -XX:HeapDumpPath=/root/jvm/dump.hprof -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:+PrintGCDetails -XX:+UseCMSCompactAtFullCollection -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=6666 -Djava.rmi.server.hostname=192.168.0.31 -jar /root/jvm/jvm-web-0.0.1-SNAPSHOT.jar > catalina.out &

ここで、JVMパラメーターの意味を挿入する必要があります。

詳細なJVMパラメーター:

JVMパラメータの意味

-XX:-CMSPrecleaningEnabled
プレクリーニングを実行しません以前の記事に合格した人は、CMSがマーキングとマーキングを同時に行う期間中にプレクリーニングジョブを実行することを知っていますこのパスは5秒以内に試行されます。 YGCが来るのを待ちます。新世代のオブジェクトをマークするために、後の再マーキングフェーズで多くの時間を費やさないようにするためです。

-XX:+ UseConcMarkSweepGC
このパラメーターは、CMSコレクターを開始します。デフォルトの新世代はParNewですが、Serialを新世代コレクターとして設定することもできます。このパラメーターは、-Xconcgcと同等です。

-XX:ParallelGCThreads
は並列プロセッサです。もちろん、スレッドの数を指定することもできます。同時スレッドのデフォルト数は(ParallelGCThreads + 3)/ 4)です。
-XX:ConcGCThreads
または-XX:ParallelCMSThreads;上記のスレッドを設定する方法に加えて、これら2つのパラメーターのいずれかを使用して同時CMSスレッドの数を手動で設定することもできます。

-XX:CMSInitiatingOccupancyFraction
CMSコレクターは排他的ではないため、アプリケーションはガベージコレクション中に引き続き機能します。そのため、アプリケーション用に十分なメモリを残す必要があります。そうしないと、FGCがトリガーされます。そして、CMS GCはいつ実行されますか?旧世代のメモリ使用率を表すこのパラメータで設定できます。このしきい値に達すると、CMSが実行されます。デフォルトは68です。古い世代のメモリが急速に増加する場合は、FGCを回避するためにしきい値を下げることをお勧めします。増加が遅い場合は、しきい値を上げてCMSGCの数を減らすことができます。スループットを向上させます。

-XX:+ UseCMSCompactAtFullCollection
CMSはマーククリーニングアルゴリズムを使用するため、メモリの断片化を回避することはできません。このパラメーターは、各CMS後のデフラグメンテーションを指定します。

-XX:CMSFullGCsBeforeCompaction各デフラグメントはパフォーマンスに影響するため、このパラメーターを使用して、CMSがデフラグされる回数(メモリ圧縮)を設定できます。

-XX:+ CMSClassUnloadingEnabled
により、クラスメタデータのリサイクルが可能になります。

-XX:CMSInitiatingPermOccupancyFraction

永続的な領域占有率がこのパーセンテージに達したら、CMSリサイクルを開始します(-XX:+ CMSClassUnloadingEnabledがアクティブ化されている場合)。

-XX:UseCMSInitiatingOccupancyOnly

CMSリカバリがしきい値に達したときにのみ実行されることを示します。

XX:CMSWaitDuration = 2000
CMS GC条件は比較的単純であるため、JVMには古い領域を定期的にスキャンするスレッドがあります。時間間隔はこのパラメーター(ミリ秒単位)で指定でき、デフォルトは2秒です。
JVMツールパラメータ:
JVMパラメータの意味


-XX:+ PrintGCDateStamps GCログのタイムスタンプを出力し
ます-XX:+ PrintGCDetails GCの詳細を出力し
ます-XX:+ PrintGCTimeStampsガベージコレクションの実行を開始するのにかかる時間を
出力します-Xloggc:ガベージコレクション情報を指定したファイルに出力します
-verbose: gc印刷GCログ
-XX:+ PrintGCApplicationStopedTime gc
XX:+ PrintTenuringDistributionログによるオブジェクトプロモーションの表示アプリケーションの一時停止時間
-XX:+ HeapDumpOnOutOfMemoryErrorメモリがオーバーフローしたときにダンプファイルを出力します

ここに写真の説明を挿入

開始効果:ここに写真の説明を挿入

アクセス:ここに写真の説明を挿入

putのリクエスト:http:からputメソッドにアクセスした後の効果を見てみましょう。ここに写真の説明を挿入

ここに写真の説明を挿入
ここに写真の説明を挿入
ここに写真の説明を挿入
手術中に、多数の物体が老朽化し、完全なgcをトリガーし、cmsが収集されていることがわかりました。

使用率は99%に達し、cmsは一瞬止まりませんでした。ここに写真の説明を挿入

ログ分析ここに写真の説明を挿入

ログ分析1.0バージョン:分析するログを抽出します

[GC(割り当ての失敗)0K-> 63K(64K)、0.0047147秒] 10258K-> 6780K(46144K)、[メタスペース:3434K-> 3434K(1056768K)]、0.0047613秒] [時間:ユーザー= 0.02 sys = 0.00、 real = 0.00秒]ログには4つの部分があります。

フルGC:

ガベージコレクションが実行され、前に完全な変更がないことを示します。これはマイナーGCであることを示します。これは、新世代のみがGCであるという意味ではなく、既存のSTWが新世代か旧世代かに関係なくSTWになることに注意してください。

割り当ての失敗:

今回のGCの原因は、若い世代に新しいデータを保存するのに十分なスペースがないためであることを示しています。

10258K-> 6780K(46144K)、単位はKB

3つのパラメータは、GC前のメモリ領域(ここでは若い世代)の使用容量、GC後のメモリ領域の使用容量、およびメモリ領域の合計容量です。

0.0047613秒:

このメモリ領域で費やされたGC時間(秒単位)

[時間:user = 0.04 sys = 0.00、real = 0.01秒]:

それぞれ、時間のかかるユーザーモード、時間のかかるカーネルモード、および時間のかかる合計を表します。 ここに写真の説明を挿入

Log Analysis 2.0バージョン:

図に示すように、分析にオンラインgceasyを使用して、Webサイトを開き、生成したgcログをアップロードします。 ここに写真の説明を挿入

最適化の問題:新世代および旧世代のメタスペースメモリ使用量について、最適化できる4つの問題がリストされています。 ここに写真の説明を挿入

スループット統計:
ここに写真の説明を挿入
各世代のメモリ変更の97.39%
ここに写真の説明を挿入

さまざまな期間でのCMSガベージコレクターの時間

ここに写真の説明を挿入
ここに写真の説明を挿入
GC発生時間の分類と時間のかかる
ここに写真の説明を挿入

位置決めの問題

作成されたスナップショットファイルを使用して、問題を特定しますここに写真の説明を挿入
。JProfiler:

ArrayListコレクションがメモリの96%を占めることがわかった、JProfiler ここに写真の説明を挿入
Viewの大きなオブジェクトここに写真の説明を挿入
介してローカルのオープンビューにダウンロードされた後、ArrayListコレクションここに写真の説明を挿入
多用するコードを調べて、ここに写真の説明を挿入
putメソッドで見つけたコードで対応するコードを見つけます。ArrayListコレクションの広範な使用によって引き起こされたメモリオーバーフローOOM

総括する

私は誰もが上記の実際の戦闘を理解していると信じています。一般的なプロセスは次のとおりです。

1.SpringBootプロジェクトの実際の大量ユーザーシナリオをシミュレートするのに十分

2. JVMパラメータを構成してから、実行中の監視データを展開してログファイルを生成します

3.ログファイルを分析して問題を確認します。
上記のコードとソフトウェアを必要とする友人は、詳細な研究計画、インタビューの質問なども持っています。インタビューは非常に明確だと思います。インタビュー情報のみを取得するには:ここをクリックして取得してください!!!パスワード:CSDN誰でも自分で行うことができます実際の操作で印象を深めます。ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/a3961401/article/details/109407949