序文 最近、4 年間実行されている Java EE Web プロジェクトでは、システムが開けないというフィードバックを顧客から頻繁に受けています。サービスを確認するためにサーバーにログインしたところ、Tomcat が自動的にシャットダウンされていることがわかりました。基本的には3〜4日ごとに発生します。 運用および保守担当者は当初、他のサービスが Tomcat サービスを強制終了したと考え、深刻に受け止めませんでした。解決策は、Tomcat を直接再起動することでした。 結局、事態は手に負えなくなり、運用・保守担当者は顧客から苦情を受け、1か月分の業績給を差し引かれました。 このバグの解決策は、紆余曲折を経て思いつきました。タスクを受け取ったら、あとは作業するだけです。解決できないバグはありません。 システムの動作環境は次のとおりです。
ログを確認してください。Tomcat がクラッシュした場合、Tomcat の bin ディレクトリに「hs_err」で始まるログ ファイルが生成されます。最新のログ ファイルを開くと、最初に次の段落が表示されます。 # Java Runtime Environment を続行するにはメモリが不足しています。 # ネイティブ メモリ割り当て (malloc) が ChunkPool::allocate に 32756 バイトを割り当てることができませんでした # 考えられる理由: # システムの物理RAMまたはスワップ領域が不足しています # 32ビットモードでは、プロセスサイズの制限に達しました # 考えられる解決策: # システムのメモリ負荷を軽減 # 物理メモリまたはスワップ領域を増やす # スワップバッキングストアがいっぱいかどうか確認する # 64 ビット OS で 64 ビット Java を使用する # Java ヒープサイズを減らす (-Xmx/-Xms) # Javaスレッドの数を減らす # Java スレッドのスタック サイズを減らす (-Xss) # -XX:ReservedCodeCacheSize= でより大きなコードキャッシュを設定します # この出力ファイルは切り捨てられているか不完全である可能性があります。 # # メモリ不足エラー (allocation.cpp:211)、pid=7864、tid=6556 # # JRE バージョン: Java(TM) SE ランタイム環境 (7.0_79-b15) (ビルド 1.7.0_79-b15) # Java VM: Java HotSpot(TM) Server VM (24.79-b02 混合モード windows-x86) # コアダンプの書き込みに失敗しました。 おそらく、32756 バイトのスペースを割り当てるのに十分なメモリがないことを意味します。解決策をいくつか紹介します。 1. システムメモリの負荷を軽減します。 2. 物理メモリまたはスワップ領域を増やす。 3. 64 ビット オペレーティング システムで 64 ビット JDK を使用します。 4. Java ヒープ サイズを減らします。 5. Java スレッドの数を減らします。 6. Java スレッドのスタック サイズを減らします。 上記の内容から、jvm は 32756 バイトのメモリ領域を割り当てることができないと結論付けることができます。 タスクを受け取った瞬間から、メモリ不足の原因は JVM 構成エラーであり、新世代と旧世代の構成を調整するだけでよいと考えていました。 ログ ファイルを確認し続けて、「GC ヒープ履歴 (10 イベント):」という行を見つけます。この行には、JVM の過去 10 回のガベージ コレクション中にヒープに加えられた変更が記録されています。 GC ヒープ履歴 (10 イベント): イベント: 572312.299 GCヒープ前 {GC 呼び出し前のヒープ = 5046 (フル 357): PSYoungGen 合計 201472K、使用済み 200685K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、100% 使用済み [0x573c0000,0x63540000,0x63540000) スペース 3328K から、76% 使用済み [0x63540000,0x637bb528,0x63880000) スペース 3328K、使用率 0% [0x63880000,0x63880000,0x63bc0000) ParOldGen 合計 843776K、使用済み 422602K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d872b18,0x573c0000) PSPermGen 合計 262144K、使用済み 51848K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e62138,0x13bc0000) イベント: 572312.305 GCヒープ後 GC 呼び出し後のヒープ = 5046 (フル 357): PSYoungGen 合計 201472K、使用済み 1103K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、使用率 0% [0x573c0000,0x573c0000,0x63540000) スペース 3328K から、33% 使用済み [0x63880000,0x63993c90,0x63bc0000) スペース 3328K、使用率 0% [0x63540000,0x63540000,0x63880000) ParOldGen 合計 843776K、使用済み 423618K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d970b18,0x573c0000) PSPermGen 合計 262144K、使用済み 51848K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e62138,0x13bc0000) } イベント: 572351.132 GCヒープ前 {GC 呼び出し前のヒープ = 5047 (フル 357): PSYoungGen 合計 201472K、使用済み 199247K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、100% 使用済み [0x573c0000,0x63540000,0x63540000) スペース 3328K から、33% 使用済み [0x63880000,0x63993c90,0x63bc0000) スペース 3328K、使用率 0% [0x63540000,0x63540000,0x63880000) ParOldGen 合計 843776K、使用済み 423618K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d970b18,0x573c0000) PSPermGen 合計 262144K、使用済み 51848K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e62138,0x13bc0000) イベント: 572351.137 GCヒープ後 GC 呼び出し後のヒープ = 5047 (フル 357): PSYoungGen 合計 201472K、使用済み 1615K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、使用率 0% [0x573c0000,0x573c0000,0x63540000) スペース 3328K から、48% 使用済み [0x63540000,0x636d3ec8,0x63880000) スペース 3328K、使用率 0% [0x63880000,0x63880000,0x63bc0000) ParOldGen 合計 843776K、使用済み 423674K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d97eb18,0x573c0000) PSPermGen 合計 262144K、使用済み 51848K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e62138,0x13bc0000) } イベント: 572398.649 GCヒープ前 {GC 呼び出し前のヒープ = 5048 (フル 357): PSYoungGen 合計 201472K、使用済み 199759K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、100% 使用済み [0x573c0000,0x63540000,0x63540000) スペース 3328K から、48% 使用済み [0x63540000,0x636d3ec8,0x63880000) スペース 3328K、使用率 0% [0x63880000,0x63880000,0x63bc0000) ParOldGen 合計 843776K、使用済み 423674K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d97eb18,0x573c0000) PSPermGen 合計 262144K、使用済み 51848K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e62138,0x13bc0000) イベント: 572398.655 GCヒープ後 GC 呼び出し後のヒープ = 5048 (フル 357): PSYoungGen 合計 201472K、使用済み 1998K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、使用率 0% [0x573c0000,0x573c0000,0x63540000) スペース 3328K から、60% 使用済み [0x63880000,0x63a73830,0x63bc0000) スペース 3328K、使用率 0% [0x63540000,0x63540000,0x63880000) ParOldGen 合計 843776K、使用済み 423703K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d985cc0,0x573c0000) PSPermGen 合計 262144K、使用済み 51848K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e62138,0x13bc0000) } イベント: 576881.689 GCヒープ前 {GC 呼び出し前のヒープ = 5049 (フル 357): PSYoungGen 合計 201472K、使用済み 200142K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、100% 使用済み [0x573c0000,0x63540000,0x63540000) スペース 3328K から、60% 使用済み [0x63880000,0x63a73830,0x63bc0000) スペース 3328K、使用率 0% [0x63540000,0x63540000,0x63880000) ParOldGen 合計 843776K、使用済み 423703K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d985cc0,0x573c0000) PSPermGen 合計 262144K、使用済み 51850K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e62850,0x13bc0000) イベント: 576881.696 GCヒープ後 GC 呼び出し後のヒープ = 5049 (フル 357): PSYoungGen 合計 201472K、使用済み 3155K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、使用率 0% [0x573c0000,0x573c0000,0x63540000) スペース 3328K から、94% 使用済み [0x63540000,0x63854cb0,0x63880000) スペース 3328K、使用率 0% [0x63880000,0x63880000,0x63bc0000) ParOldGen 合計 843776K、使用済み 423703K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d985cc0,0x573c0000) PSPermGen 合計 262144K、使用済み 51850K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e62850,0x13bc0000) } イベント: 580535.452 GCヒープ前 {GC 呼び出し前のヒープ = 5050 (フル 357): PSYoungGen 合計 201472K、使用済み 201299K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 198144K、100% 使用済み [0x573c0000,0x63540000,0x63540000) スペース 3328K から、94% 使用済み [0x63540000,0x63854cb0,0x63880000) スペース 3328K、使用率 0% [0x63880000,0x63880000,0x63bc0000) ParOldGen 合計 843776K、使用済み 423703K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d985cc0,0x573c0000) PSPermGen 合計 262144K、使用済み 51856K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e64228,0x13bc0000) イベント: 580535.459 GCヒープ後 GC 呼び出し後のヒープ = 5050 (フル 357): PSYoungGen 合計 200960K、使用済み 1858K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 197632K、使用率 0% [0x573c0000,0x573c0000,0x634c0000) スペース 3328K から、55% 使用済み [0x63880000,0x63a50be0,0x63bc0000) スペース 3584K、使用率 0% [0x634c0000,0x634c0000,0x63840000) ParOldGen 合計 843776K、使用済み 423703K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d985cc0,0x573c0000) PSPermGen 合計 262144K、使用済み 51856K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e64228,0x13bc0000) } 上記の内容を読んだ後、Tomcat フラッシュ クラッシュが、古い世代、永続的な世代、および新しい世代のスペース不足によって発生したとはわかりませんでした。 Eden 領域の使用率が 100% に達したためにフル GC が数回発生しましたが、ガベージ コレクション後、Eden 領域のスペースは通常のレベルに戻りました。 ログには、Tomcat がクラッシュしたときのヒープ使用量も記録されます。 ヒープ PSYoungGen 合計 200960K、使用済み 95671K [0x573c0000、0x63bc0000、0x63bc0000) エデン スペース 197632K、47% 使用済み [0x573c0000,0x5cf5d230,0x634c0000) スペース 3328K から、55% 使用済み [0x63880000,0x63a50be0,0x63bc0000) スペース 3584K、使用率 0% [0x634c0000,0x634c0000,0x63840000) ParOldGen 合計 843776K、使用済み 423703K [0x23bc0000、0x573c0000、0x573c0000) オブジェクト スペース 843776K、50% 使用済み [0x23bc0000,0x3d985cc0,0x573c0000) PSPermGen 合計 262144K、使用済み 51856K [0x03bc0000、0x13bc0000、0x23bc0000) オブジェクト スペース 262144K、19% 使用済み [0x03bc0000,0x06e64228,0x13bc0000) すべてがとても普通でしたが、同時にとても奇妙でした。 過去のログを確認しましたが、内容は似ていました。 私はログを数回読み直し、今回はログに提案されている解決策に焦点を当てました。 # システムのメモリ負荷を軽減 # 物理メモリまたはスワップ領域を増やす # スワップバッキングストアがいっぱいかどうか確認する # 64 ビット OS で 64 ビット Java を使用する # Java ヒープサイズを減らす (-Xmx/-Xms) # Javaスレッドの数を減らす # Java スレッドのスタック サイズを減らす (-Xss) 以下の解決策は採用されません。
残る解決策は次の 3 つだけです。
Java スレッドの数を減らすにはコードを変更する必要があり、これも現実的ではありません。 最後に、
これらが2つの解決策です。ここから始めれば、前途に光が見えてきます。 Javaスレッドスタックサイズを減らす(-Xss)ソリューションの初見 Java スレッドを実行するにはメモリ領域も必要です。-Xss パラメータは、各スレッド スタックのサイズと、JVM によって開始された各スレッドに割り当てられるメモリ サイズを指定します。 JDK 1.4 では 256K、JDK 1.5 以上では 1M です。 tomcat jvm のパラメータは次のように設定されます。 JAVA_OPTS=%JAVA_OPTS% -server -Xms1024m -Xmx1024m -Xmn200M -XX:PermSize=256M -XX:MaxPermSize=512m -XX:SurvivorRatio=1 -Xss256k 各 Java スレッドのスタック サイズは、-Xss によって 256K に設定されています。 Java 言語では、スレッドを作成すると、仮想マシンは JVM メモリ内に Thread オブジェクトを作成し、同時にオペレーティング システム スレッドを作成します。このシステム スレッドのメモリは JVMMemory ではなく、システム内の残りのメモリ (MaxProcessMemory - JVMMemory - ReservedOsMemory) です。 スレッドを作成する必要があり、オペレーティング システムの残りのメモリが Java スレッドに割り当てるのに不十分な場合は、メモリ不足エラーが報告されます。 Java スレッド スタック サイズは -Xss によって 256K に設定されているため、このソリューションは使用しないことに決定されました。 残された唯一の解決策は、Java ヒープ サイズを減らす (-Xmx/-Xms) ことです。ヒープ サイズを縮小すると、Java スレッド スタックに十分なメモリ領域が確保されます。 32 ビット Windows オペレーティング システムでは、ヒープ最大容量と PermSize の最大容量を差し引いた 2G のメモリ領域が各プロセスに割り当てられ、残りの容量は Java スレッド スタック用に予約されます。 コードと以前のエラー ログを分析した結果、メモリ不足エラーは通常 350 スレッド付近で発生することがわかりました。 変更された jvm パラメータは次のとおりです。 JAVA_OPTS=%JAVA_OPTS% -server -Xms768m -Xmx768m -Xmn200M -XX:PermSize=256M -XX:MaxPermSize=512m -XX:SurvivorRatio=1 -Xss256k これまでのところ、システムは 1 か月間安定して稼働しており、すべてのパラメータ指標は正常範囲内です。最大ヒープ使用量はわずか 70% です。 要約: 1. 今回のバグを解決した後、Java 仮想マシン、特にスレッド スタック、メモリ ヒープ、永続世代、新規世代などの概念についての理解が深まりました。 2. ログ ファイルを注意深く読み、潜在的な解決策を段階的に排除してください。総合的なシステムの動作環境を考慮し、適切な解決策を見つけます。 さて、今回の記事は以上です。この記事の内容が皆さんの勉強や仕事に少しでも参考になれば幸いです。123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
>>: 関数の分類の詳細な説明とJavascriptでのこのポイントの例
目次前面に書かれた双方向暗号化エンコード/デコードAES_ENCRYPT/AES_DECRYPT D...
目次0x0 はじめに0x1 RBAC 実装0x2 クレームベースの承認0x3 統合 CASL 0x4...
達成すべき効果: 必要なもの1枚、2枚、3枚とスタイルが異なります。子要素の判定はjsで完結できます...
この記事には、細かい点は一切なく、カラーマッチングのテクニックをシェアするだけです。とてもシンプルで...
docker アタッチコマンドdocker attach [options] 容器実行中のコンテナに...
コードは次のようになります。 SELECT @i:=@i+1 行番号、 if(@total=t.s_...
プロジェクトで使用されている特殊文字とアイコンHTMLコードXML/HTML コードコンテンツをクリ...
この記事では、参考までに、簡単なタイマー機能を実装するためのvue.jsの具体的なコードを紹介します...
主に2つの側面から: 1. ハイライト/改行2. コードのコピーボタンこれら両方には既製のプラグイン...
この記事ではMySQL 5.7.20のインストールと設定方法を記録し、皆さんと共有します1. MyS...
1. ユーザーを作成します。注文: 'password' によって識別される ...
目次数学オブジェクト共通プロパティ一般的な方法Math.random()文字列メソッド長さプロパティ...
重要なイベントまであと何日あるか知りたいですか? Linux bash と date コマンドが役に...
水平スクロールはあらゆる状況に適しているわけではありませんが、適切に行えば、Web サイトを他のサイ...
MySQL バックアップコールドバックアップ:停止服務進行備份,即停止數據庫的寫入ホットバックアップ...