【生産ライン事故】生産ライン事故のOOMを共有

序文

前回のオンライン CPU アラームに続いて、今回はサービスが再開されました. 数日落ち着いた後、運用ログ サービスの実行を監視すると、OutOfMemoryError が頻繁に表示されました.これは、一般的に OOM と呼ばれています. OOM が頻繁に発生すると、サービスが利用できない状況に直接陥ります. Skywalking を介してリンク呼び出しを確認すると、基本的にすべてのレポートが赤くなり、基本的に麻痺状態になります.直ちにサービスを停止し、再起動します、B サイド製品であるため、まず会社のビジネスに使用させ、サービスの正常な使用を確保してから、問題を緊急に確認し、根本原因を見つけて修正します。

OutOfMemoryError の理由

まず OutOfMemoryError の理由を理解しましょう。これは 2 つのタイプにすぎません堆内存空间不足元空间不足

  • ヒープ メモリ領域が不足しています: を意味します程序存在一直有引用的对象(强引用),主要对象在引用的状态就无法被GC回收,撑爆了-Xmx堆拓展的最大值,内存不足自然就会触发堆内存溢出
  • メタスペース: Java 8 では、以前のヒープの永続的な生成を置き換えるメタスペースの概念が導入されました. メタスペースはオフヒープ メモリに属しているため、オブジェクト参照は必要ありません. クラスとメタデータはポインターによって表されます. その理由この種の JDK アップグレードの最適化により、永続世代のメモリ オーバーフローが回避されます。

一般的なヒープ メモリ オーバーフローのいくつかの状況

  • クエリ データベースから返されるデータの量が多すぎるため、メモリに読み込まれ、メモリ オーバーフローが発生します。
  • コードに無限ループがあり、ラージ オブジェクトが参照され、GC で再利用できません。
  • リソース リンク プールと io ストリームは、使用後に手動で解放されません。
  • 静的コレクション クラスには参照オブジェクトがあり、クリアされていない参照関係が常に存在します。

上記は、一般的なヒープ メモリ オーバーフローのシナリオの一部です. もちろん、時々、私たちが遭遇する問題は奇妙で奇妙です. 一般的な問題は常にめったに遭遇しません.

現象解析

本番環境のエラーログによると、これはMybatisが報告しているメモリオーバーフローで、Mybatisのソースコードを見ると、最下層もいくつかのコレクションクラスを使ってつなぎ合わせたSQLを格納していることがわかるので、もちろんヒープ メモリ オーバーフローが発生する可能性があり、比較的大きな sql ボリュームの場合、受信 sql のセットが非常に大きくなり、再利用できない場合はメモリ オーバーフローが発生します。

主な理由Mybatis拼接SQL的时候生成的占位符和参数对象,存放在Map里,当SQL的参数多导致SQL太长的时候,Map持有这些SQL时间较长,并且多线程同时操作,这时候内存占用就很高,从而发生OOM

Mybatis ソースコード分析

DynamicContext クラスのソース コードを見ると、DynamicContext には、
HashMap を継承し、Map コレクションに相当する ContextMap タイプの別のパラメーター バインディングがあります。 . 簡単に言えば, ForEachSqlNode pass getBindings メソッドは SQL パラメーターとパラメーター プレースホルダーを ContextMap コレクションに均一に配置します. 主な理由は、パラメーターとプレースホルダーが GC によって再利用できず、多数の同時クエリがある場合に OOM が発生するためです.

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

シナリオの再発

次にオンラインの様子を再現したところ、SQL文をつなぎ合わせてIN内のパラメータを大きくし、実行スレッドを50スレッド作成し、JVMヒープメモリを-Xmx256m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryErrorに設定

ここに画像の説明を挿入
ここに画像の説明を挿入

ここでコンソールに出力されたログを見ると、サービスは頻繁にフル GC を実行しており、OOM が発生しています。
ここに画像の説明を挿入

要約する

問題の原因が判明したので、次のステップはコード SQL を最適化することです.SQL をつなぎ合わせるときにボリュームが大きくなりすぎないようにします.ここで、コードをむやみに記述しないように注意し、SQL文は勝手に書いてはいけません. 時々私たちは問題について考えます.

おすすめ

転載: blog.csdn.net/u011397981/article/details/130034305