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誰でも自分で行うことができます実際の操作で印象を深めます。