質問者: オンラインで OOM に遭遇した場合、どうやって解決しますか?
OOM は開発者にとって最も恐れられる問題の 1 つと言えますが、その原因は基本的にコードまたは JVM パラメーターの設定にあります。
この記事では、Java プロセスが OOM をトリガーした後のトラブルシューティング方法について読者に説明します。
実稼働環境には畏敬の念を抱いているとよく言われますが、問題を迅速に解決することも畏敬の念の表れです

OOM が起こる理由
OOM は「Out Of Memory」の略で、メモリが使い果たされていることを意味します。 JVM にオブジェクトにスペースを割り当てるのに十分なメモリがなく、ガベージ コレクターにリサイクルするスペースがない場合、このエラーがスローされます。
OOM はなぜ発生しますか? 通常、これらの問題が原因で発生します
割り当てが少なすぎます: JVM 初期化メモリが小さく、ビジネスで大量のメモリが使用されているか、さまざまな JVM 領域へのメモリ割り当てが不当です - # #コードの脆弱性: 特定のオブジェクトが頻繁に適用されるが、使用されないまま解放されず、メモリが枯渇する
#メモリリーク: アプリケーションが解放されずに使用されるメモリこのメモリを使用すると、仮想マシンが再度使用できなくなります。このメモリはリークされます。申請者はもう使用されておらず、仮想マシンによって他の申請者に割り当てることはできないため
メモリ オーバーフロー: 要求されたメモリが、JVM が提供できるメモリ サイズを超えています。これは、アプリケーションと呼ばれます。オーバーフロー
メモリ リークは持続し、最終的にはオーバーフローします。この 2 つは因果関係があります。一般的な OOM
より一般的な OOM タイプには、次のようなものがあります。java.lang.OutOfMemoryError: PermGen space
Java7 永続生成 (メソッド領域) オーバーフロー。これは使用されます。データを格納します。クラス情報、定数、静的変数、仮想マシンによってロードされたジャストインタイム コンパイラによってコンパイルされたコードなど。クラスが初めてロードされるたびに、メタデータは永続的な世代に保存されます通常、多数の Class オブジェクトまたは JSP ページに表示されるか、CgLib 動的プロキシ テクノロジの使用によって
-XX: PermSize
および -XX を渡すことができます。 : MaxPermSize
メソッド領域のサイズを変更します
Java8 が永続世代をメタスペースに変更すると、エラーが報告されます: java.lang.OutOfMemoryError: メタデータ スペース、メタスペース メモリが不足しており、デフォルトで動的に展開されます
java.lang.StackOverflowError
仮想マシンのスタック オーバーフローは、通常、## の存在によって発生します。プログラム内の #無限ループまたは深い再帰呼び出し 。スタック サイズが小さすぎると、オーバーフローが発生します。-Xss
java.lang.OutOfMemoryError: Java heap space
Java ヒープ メモリ オーバーフロー、オーバーフローの原因は一般的に次のとおりです。不当な JVM ヒープ メモリ設定またはメモリ リークにより、
メモリ リークが発生した場合は、ツールを使用して、リークしたオブジェクトから GC ルートまでの参照チェーンを表示できます。リークしたオブジェクトの型情報と GC ルート参照チェーン情報を把握することで、リークしたコードの場所を正確に特定できます。メモリ リークがない場合、つまり、メモリ内のオブジェクトがまだ残っている必要があります。生きている場合は、仮想マシンのヒープ パラメータ (-Xmx および -Xms) をチェックして、仮想マシンのメモリを増やすことができるかどうかを確認する必要があります。概要: メソッド領域とメソッド領域のオーバーフロー シナリオ仮想マシン スタックについては、この記事ではあまり説明しません。以下では主に、Java ヒープ スペースに関する一般的な OOM トラブルシューティングのアイデアについて説明します。JVM メモリ分布を確認する
Java アプリケーションの PID が 15162 であるとします。コマンドを入力して 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 の実行中に最もリソースを消費するオブジェクトを表示できます (jmap -histo:live 15162 | more
JVM メモリ オブジェクトのリストは次に従ってソートされています)オブジェクトによって占有されるメモリ サイズ
instances: インスタンスの数 #bytes: 単位バイト クラス名: クラス名

CustomObjTest
オブジェクト インスタンスと過剰なメモリ使用量
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 二进制文件在当前文件夹下

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

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

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

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

文中 Dump 文件较为简单,而正式环境出错的原因五花八门,所以不对该 Dump 文件做深度解析
注意:JvisualVM 如果分析大 Dump 文件,可能会因为内存不足打不开,需要调整默认的内存
概要レビュー
オンラインで JVM メモリ オーバーフローが発生した場合は、次の手順でトラブルシューティングを行うことができます
jmap -heap
メモリ割り当てが小さすぎるかどうかを確認します##jmap -histo 明らかなオブジェクトがあるかどうかを確認します割り当て リリースは多数あり、リリースはありません。
jmap -dump JVM の現在のメモリ スナップショットをエクスポートし、JDK や MAT などのツールを使用してスナップショットを分析します
以上が質問者: オンラインで OOM に遭遇した場合、どうやって解決しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです
