Java プログラムが JVM 上で実行されることは誰もが知っています。 JVM に何らかの障害が発生すると、サービスの安定性が必然的に影響を受けます。運が良ければ、サービスが不安定になり、一部のリクエストが遅延したり異常になったりする可能性があります。運が悪いと、JVM が直接クラッシュし、サービスが完全に中断されることになります。 これは良いことではありません。 JVM とともに、サービスだけでなく私たちの精神も崩壊するでしょう。 いわゆる JVM クラッシュは、一般的にメモリ オーバーフロー、つまり OutOfMemoryError と StackOverflowError を指します。もう 1 つの状況は、オフヒープ メモリの使用量が非常に大きい場合です。これにより、JVM が配置されているマシンのメモリが膨張し、マシンの再起動などの異常な状況が発生します。この状況をメモリ リークと呼びます。 では、どのような状況で JVM がクラッシュするのでしょうか?クラッシュにはどのような種類がありますか?諺にあるように、自分と敵を知ることによってのみ、百戦錬磨の勝者となることができるのです。クラッシュの原因を理解することによってのみ、JVM クラッシュの問題をより適切に解決できます。 まず、JVM メモリ モデル図を示します。 JVM は理解するのが非常に抽象的です。次の図は、JVM メモリ モデルを具体的に理解するのに役立ち、オーバーフローが発生する部分も図で確認できます。 JDK 8 では、永続世代は存在しなくなり、メタスペースに置き換えられました。 次に、Hotspot JDK 8 を背景として、JVM メモリ オーバーフローとメモリ リークのいくつかのケースを見ていきます。 まず、ヒープ領域のサイズを制限するために JVM 起動パラメータを設定します。ヒープ領域は、新世代用に 10M、メタスペース用に 10M を含む 20M に設定され、ガベージ コレクション アルゴリズムとして CMS アルゴリズムを使用するように指定します。以降のすべての例では、このパラメータ セットを使用します。
ヒープオーバーフロー ヒープ オーバーフローは、おそらく最も一般的なメモリ オーバーフローのシナリオです。 JVM に割り当てられたほとんどのオブジェクト インスタンスと配列はヒープ上に格納されます。さらに、ヒープメモリはガベージコレクターの主戦場でもあります。 Java プログラムが起動すると、ヒープ領域のサイズが指定されます。新しいオブジェクトと配列が作成されると、それらはヒープ上に割り当てられます。新しいオブジェクトがスペースを要求したときに、ヒープ メモリが不足している場合は、ガベージ コレクションが発生します。ほとんどの場合、これはマイナー GC と呼ばれる新しい世代で発生します。新しい世代が収集されてもまだ十分なスペースがない場合は、FullGC が発生します。 FullGC後も領域が不足している場合は、OOMエラー(ヒープオーバーフロー)が発生します。 このシナリオをシミュレートする
上記の方法は、 以下はプログラムを実行した後の結果です。ガベージ コレクション後も余分なスペースがないため、java.lang.OutOfMemoryError: Java ヒープ スペース例外が発生します。 画像-20201016211017630 ヒープ メモリ オーバーフローの根本的な原因は、使用中のオブジェクトのサイズがヒープ メモリ サイズを超えていることです。 ヒープメモリスペースの設定が小さすぎます。推定される実際のヒープ サイズに基づいて、ヒープ領域を適切に設定する必要があります。 プログラムの脆弱性により、一部の静的変数が増大し続けます。たとえば、キャッシュ データの初期化が不適切だと、キャッシュが際限なく大きくなり、最終的にはヒープ メモリのオーバーフローが発生します。この状況には、適切なテストを実施し、問題が発生した後に適切なログ分析を行う以外に、おそらく適切な解決策はありません。 スタックオーバーフロー 仮想マシン スタックは、ローカル変数テーブル、オペランド スタック、動的リンク、メソッド終了などの情報を格納するために使用されます。Java メソッドが呼び出されるたびに、仮想マシン スタック内にこのメソッドのスタック フレームが生成されます。 スタックには、仮想マシン スタックに加えて、ネイティブ メソッド スタックも含まれます。呼び出されたメソッドがネイティブ メソッド (C 言語で実装されたメソッドなど) の場合、ネイティブ メソッド スタックが使用されます。ただし、HotSpot 仮想マシンでは、仮想マシン スタックとローカル メソッド スタックが 1 つに結合されます。 スタックオーバーフローのシナリオをシミュレートする
上記のコードでは、stackOverflow() メソッドの呼び出しは、再帰終了のない無限再帰プロセスです。前述したように、メソッドが呼び出されるたびに、仮想マシン スタックにスタック フレームが生成されます。無限再帰は必然的にスタック フレームの無限生成を引き起こし、最終的にはスタック領域がいっぱいになり、オーバーフローが発生します。 画像-20201019122447325 上記は最も一般的な状況をシミュレートしたものです。この状況の原因はおそらくプログラムのバグによるものです。一般的に言えば、再帰には再帰的な終了が必要です。何らかの理由でプログラムが実行中に終了条件に到達できない場合、この例外が発生します。ループ本体もございます。ループ本体の反復回数が多すぎると、スタック オーバーフローが発生する可能性があります。 スレッドが多すぎるなど、可能性の低い他の理由もあるかもしれません。スレッドを作成するには、仮想マシン スタックにスペースを割り当てる必要があります。作成されるスレッドが多すぎると、OutOfMemoryError 例外が発生する可能性があります。ただし、一般的には手動でスレッドを作成するのではなく、スレッド プール方式を使用するため、このような状況が発生する可能性は低くなります。 メタスペース オーバーフローは、クラス情報、定数、静的変数、ジャストインタイム (JIT) コンパイル コード、および仮想マシンによってロードされたその他のデータを格納するために使用されます。 JDK 8 では、permanent 世代の代わりに metaSpace が使用されています。デフォルトでは、metaSpace のサイズは無制限、つまりサーバーの実際のメモリ サイズになります。ただし、一般的には、メタスペースのサイズを設定するのが最適です。 一般的に、動的に生成されるクラスが大量に生成されると、メタスペースのメモリ オーバーフローが発生する可能性があります。 メタスペースオーバーフローのシミュレーション
CGLIB を通じて多くの動的クラスを動的に作成すると、メタスペースに格納されるクラス情報が増え、メタスペース オーバーフローが発生します。 画像-20201019163227576 たとえば、Spring や MyBatis などの技術フレームワークを使用する場合、Bean インスタンス クラスが動的に作成されます。さらに、Spring AOP は動的プロキシ クラスも生成します。 オフヒープメモリオーバーフロー ほとんどの場合、メモリは JVM ヒープ メモリ内に割り当てられますが、まれにヒープ外部に直接メモリ領域を割り当てる必要がある場合もあります。オフヒープメモリを使用することによる利点はいくつかあります。
通常、オフヒープ メモリは、大量の頻繁な IO 操作が必要な場合に使用されます。たとえば、Netty と RocketMQ はオフヒープ メモリを使用してプロセスを高速化します。 したがって、システム メモリの使用量が非常に大きい場合は、スタックをチェックしても結果が出なかった場合、オフヒープ メモリの使用量をチェックして、オフヒープ メモリがオーバーフローしていないかどうかを確認できます。 要約する 事前に設定を行ってください JVM の問題自体は比較的抽象的で直感的に発見するのが難しいため、プロジェクトがオンラインになる前に、コード ロジックをテストするだけでなく、スタック サイズ、ガベージ コレクターの種類など、アプリケーションのサイズと特性に応じて JVM パラメータを合理的に構成し、適切なパラメータを選択することも必要です。 さらに、ガベージ コレクション ログを保持し、メモリ オーバーフローが発生したときにダンプ ファイルを保存する必要があります。 プロセスを監視する プログラムがオンラインのときは、Spring Admin などの軽量監視ツールを使用したり、大規模なプロジェクトの場合は Cat や SkyWallking などの分散リンク監視システムを使用したりして、JVM を適切に監視します。 現場での保護とその後の分析を提供する パラメータ構成と監視プラットフォームがどれほど合理的であっても、例外は必ず発生します。これは正常です。例外がない場合にのみ問題が生じます。例外が発生した後、シーンはタイムリーに保存される必要があります。マルチインスタンス アプリケーションの場合は、例外が発生したインスタンスを一時的にオフラインにして、問題をトラブルシューティングすることができます。単一インスタンスのサービスの場合は、最新のログとダンプが保存されていることを速やかに確認する必要があります。確認後、サービスを再起動するアクションを実行します。 この記事はWeChatの公開アカウント「古代の凧」から転載したものです。下のQRコードからフォローできます。この記事を転載する場合は、Ancient Kite の公開アカウントにご連絡ください。 |
<<: 専門家の予測:2021年にクラウドコンピューティング分野で出現するトレンド
>>: VMware が 3 年連続で Gartner Magic Quadrant の WAN エッジ インフラストラクチャのリーダーに選出
多くの企業ユーザーは、企業内にパブリック クラウド プラットフォームを展開するのは、プライベート ク...
資本は複数の当事者間の激しい競争を促進する「タオバオ+天猫」の取引高1兆元は、2012年の熾烈な競争...
第三者市場調査会社カナリスの調査によると、米国企業によるクラウドコンピューティングインフラサービスへ...
BBS西集胡同コミュニティの創設者、翔馬(劉虎)の仕事写真。シナテクノロジー トレーシー孔子は「40...
Internet of Everythingの時代の到来により、IoTデバイスの数は爆発的に増加しま...
筆者は2月2日に「医療SEMにおけるWeb編集者の手ほどき」を公開したが、友人から実践は難しいと言わ...
ネットワーク仮想化の概念は長い間提案されてきましたが、その具体的な定義は業界では依然として議論の的と...
今日、ますます多くの企業が、優れたパフォーマンスを利用してワークロードを最適化し、効率的に処理するた...
数え切れないほどの噂の後、Sogou はついに目的地を見つけました。テンセントはSogouに4億48...
資本市場で何度も上場の噂が流れていた小紅書は、最新の資金調達ラウンドを迎えた。 11月8日、メディア...
国内では、ウェブサイトを構築できる人なら誰でも基本的にSEOサービスを提供できるようになっていること...
今年から事業を開始した VPS ベンダーの launchvps は、レイバー デー ギフトとして特別...
この記事はアプリの宣伝方法についての著者の理解です。お役に立てれば幸いです。お楽しみください〜 1....
コンテンツこそが王様だとよく言われますが、この言葉の本当の意味を知らない人がたくさんいます。ほとんど...
Sugarhosts は 4 周年を記念して特別割引を提供しています。この割引は仮想ホスティングと ...