ホームページ  >  記事  >  Java  >  特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

Java后端技术全栈
Java后端技术全栈転載
2023-08-23 14:34:161837ブラウズ

OOM は、プログラムに脆弱性があることを意味します。コードまたは JVM パラメータ設定が原因である可能性があります。この記事では、Java プロセスが OOM をトリガーした場合のトラブルシューティング方法について読者に説明します。

実稼働環境には畏敬の念を抱いているとよく言われますが、問題を迅速に解決することも畏敬の念の表れです

特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

OOM の理由

##OOM は「Out Of Memory」の略で、メモリが使い果たされていることを意味します。 JVM にオブジェクトにスペースを割り当てるのに十分なメモリがなく、ガベージ コレクターにリサイクルするスペースがない場合、このエラーがスローされます。

OOM はなぜ発生しますか? 通常、次の問題が原因で発生します

  1. 割り当てが少なすぎます: JVM 初期化メモリが小さく、ビジネスで大量のメモリが使用されているか、さまざまな JVM 領域へのメモリ割り当てが不当です
  2. # #コードの脆弱性: 特定のオブジェクトが頻繁に適用されるが、使用されずに解放されず、メモリが枯渇する
#メモリリーク

: アプリケーションが解放されずに使用されるメモリこのメモリを使用すると、仮想マシンが再度使用できなくなります。このメモリはリークされます。申請者はもう使用されておらず、仮想マシンによって他の申請者に割り当てることはできないため

メモリ オーバーフロー

: 要求されたメモリが、JVM が提供できるメモリ サイズを超えています。これは、アプリケーションと呼ばれます。オーバーフローメモリ リークは持続し、最終的にはオーバーフローします。この 2 つは因果関係があります。

一般的な OOM

比較的一般的な OOMタイプは次のとおりです。

java.lang.OutOfMemoryError: PermGen space

Java7 永続生成 (メソッド領域) オーバーフロー。仮想マシン クラス情報、定数、静的変数、ジャストインタイム コンパイラによってコンパイルされたコード、およびその他のデータ。クラスが初めてロードされるときは常に、メタデータは永続世代に保存されます。

一般に、多数の Class オブジェクトまたは JSP ページに表示されるか、CgLib 動的プロキシ テクノロジの使用によって

が発生します。

メソッド領域のサイズは、-XX: PermSize および -XX: MaxPermSize

Java8 によって永続世代がメタスペースに変更されます。エラーが報告されます:java.lang.OutOfMemoryError: Metadata space、メタスペースのメモリが不足しており、デフォルトで動的に拡張されます

java.lang.StackOverflowError

仮想マシン スタック オーバーフロー は通常、プログラム内に 無限ループまたは深い再帰呼び出し が存在することが原因で発生します。スタック サイズが小さすぎると、オーバーフローが発生します。-Xss

を使用してスタック サイズを設定できます。仮想マシンはスタック オーバーフロー エラーをスローし、間違ったクラスが見つかる可能性があります。

java.lang.OutOfMemoryError: Java heap space

Java ヒープ メモリ オーバーフロー、オーバーフローの原因は一般的に次のとおりです。不当な JVM ヒープ メモリ設定またはメモリ リークにより、

メモリ リークが発生した場合は、ツールを使用して、リークしたオブジェクトから GC ルートまでの参照チェーンを表示できます。リークしたオブジェクトの型情報と GC ルート参照チェーン情報を把握することで、リークしたコードの場所を正確に特定できます。

メモリ リークがない場合、つまり、メモリ内のオブジェクトがまだ残っている必要があります。生きている場合は、仮想マシンのヒープ パラメータ (-Xmx および -Xms) をチェックして、仮想マシンのメモリを増やすことができるかどうかを確認する必要があります。

概要: メソッド領域とメソッド領域のオーバーフロー シナリオ仮想マシン スタックについては、この記事ではあまり説明しません。以下では主に、Java ヒープ スペースに関する一般的な OOM トラブルシューティングのアイデアについて説明します。

JVM メモリ分布の表示

Java アプリケーションの PID が 15162 であると仮定して、コマンド「Check JVM メモリ分布を確認する」を入力します。jmap -heap 15162

[xxx@xxx ~]# jmap -heap 15162
Attaching to process ID 15162, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio         = 40 # 最小堆使用比例
   MaxHeapFreeRatio         = 70 # 最大堆可用比例
   MaxHeapSize              = 482344960 (460.0MB) # 最大堆空间大小
   NewSize                  = 10485760 (10.0MB) # 新生代分配大小
   MaxNewSize               = 160759808 (153.3125MB) # 最大新生代可分配大小
   OldSize                  = 20971520 (20.0MB) # 老年代大小
   NewRatio                 = 2 # 新生代比例
   SurvivorRatio            = 8 # 新生代与 Survivor 比例
   MetaspaceSize            = 21807104 (20.796875MB) # 元空间大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB) # Compressed Class Space 空间大小限制
   MaxMetaspaceSize         = 17592186044415 MB # 最大元空间大小
   G1HeapRegionSize         = 0 (0.0MB) # G1 单个 Region 大小

Heap Usage:  # 堆使用情况
New Generation (Eden + 1 Survivor Space): # 新生代
   capacity = 9502720 (9.0625MB) # 新生代总容量
   used     = 4995320 (4.763908386230469MB) # 新生代已使用
   free     = 4507400 (4.298591613769531MB) # 新生代剩余容量
   52.56726495150862% used # 新生代使用占比
Eden Space:  
   capacity = 8454144 (8.0625MB) # Eden 区总容量
   used     = 4029752 (3.8430709838867188MB) # Eden 区已使用
   free     = 4424392 (4.219429016113281MB) # Eden 区剩余容量
   47.665996699370154% used  # Eden 区使用占比
From Space: # 其中一个 Survivor 区的内存分布
   capacity = 1048576 (1.0MB)
   used     = 965568 (0.92083740234375MB)
   free     = 83008 (0.07916259765625MB)
   92.083740234375% used
To Space: # 另一个 Survivor 区的内存分布
   capacity = 1048576 (1.0MB)
   used     = 0 (0.0MB)
   free     = 1048576 (1.0MB)
   0.0% used
tenured generation: # 老年代
   capacity = 20971520 (20.0MB)
   used     = 10611384 (10.119804382324219MB)
   free     = 10360136 (9.880195617675781MB)
   50.599021911621094% used

10730 interned Strings occupying 906232 bytes.

JVM メモリ割り当てとランタイム使用量をチェックすることで、次のことを確認できます。メモリ割り当てが適切かどうか

さらに、JVM の実行中に最もリソースを消費するオブジェクトを表示できます (jmap -histo:live 15162 | more

JVM メモリ オブジェクトのリストは次に従ってソートされています)オブジェクトによって占有されるメモリ サイズ

  • instances: インスタンスの数
  • #bytes: 単位バイト
  • クラス名: クラス名
特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

CustomObjTest オブジェクト インスタンスと過剰なメモリ使用量

## は明らかです。 #残念ながら、この解決策には限界があります。オブジェクトによる過剰なメモリ使用の問題のトラブルシューティングしかできないためです。

ここで、「[」は配列を表します。たとえば、「[C」は Char 配列を表し、「[」は配列を表します。 B" はバイト配列を表します。配列メモリが多すぎる場合、どのオブジェクトがそれを保持しているのかが分からないため、オフライン分析のためにメモリをダンプする必要があります

jmap -histo:live を実行します。このコマンドを実行すると、JVM は最初に GC をトリガーし、次に統計を収集します。

ダンプ ファイル分析

ダンプ ファイルは、次のメモリ イメージです。 Java プロセスには、主に

システム情報仮想マシンのプロパティ完全なスレッド ダンプすべてのクラスとオブジェクトのステータスなどが含まれます。情報

いつプログラムでメモリ オーバーフローまたは GC 例外が発生した場合、JVM に

メモリ リークがあると考えられます。その場合、分析のためにダンプ ファイルをエクスポートできます

次のパラメータを JVM 起動パラメータ設定に追加します

  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:HeapDumpPath=./(参数为 Dump 文件生成路径)

当 JVM 发生 OOM 异常自动导出 Dump 文件,文件名称默认格式:java_pid{pid}.hprof

上面配置是在应用抛出 OOM 后自动导出 Dump,或者可以在 JVM 运行时导出 Dump 文件

jmap -dump:file=[文件路径] [pid]

# 示例
jmap -dump:file=./jvmdump.hprof 15162

在本地写一个测试代码,验证下 OOM 以及分析 Dump 文件

设置 VM 参数:-Xms3m -Xmx3m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./

public static void main(String[] args) {
    List<Object> oomList = Lists.newArrayList();
   // 无限循环创建对象
    while (true) {
        oomList.add(new Object());
    }
}

通过报错信息得知,java heap space 表示 OOM 发生在堆区,并生成了 hprof 二进制文件在当前文件夹下

特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

JvisualVM 分析

Dump 分析工具有很多,相对而言 JvisualVMJProfilerEclipse Mat,使用人群更多一些。下面以 JvisualVM 举例分析 Dump 文件

特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

列举两个常用的功能,第一个是能看到触发 OOM 的线程堆栈,清晰得知程序溢出的原因

特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

第二个就是可以查看 JVM 内存里保留大小最大的对象,可以自由选择排查个数

特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

点击对象还可以跳转具体的对象引用详情页面

特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?

文中 Dump 文件较为简单,而正式环境出错的原因五花八门,所以不对该 Dump 文件做深度解析

注意:JvisualVM 如果分析大 Dump 文件,可能会因为内存不足打不开,需要调整默认的内存

概要レビュー

オンラインで JVM メモリ オーバーフローが発生した場合は、次の手順でトラブルシューティングを行うことができます

  1. jmap -heap メモリ割り当てが小さすぎるかどうかを確認します。
  2. jmap -histo 明らかに割り当てられすぎて解放されていないオブジェクトがないか確認します。
  3. jmap -dump JVM の現在のメモリ スナップショットをエクスポートし、JDK や MAT などのツールを使用してスナップショットを分析します。
    上記の場合 それでも問題が見つからない場合は、アプリケーションがネットワーク接続やスレッドなどのリソースを絶えず作成していないかどうかを確認する必要があります。これにより、システム リソースが枯渇する可能性があります。

以上が特定のグループへのインタビュー: オンラインで OOM に遭遇した場合、どのようにトラブルシューティングを行うべきですか?の解き方?どのようなオプションがありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はJava后端技术全栈で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。