記事では、8種類のJVMがメモリ不足(OOM)と解決策を考え出す理由

序文

Javaのラインと学生は、メモリ(OOM)のシーンのうち、多かれ少なかれ発生しますが、OOMの原因が変化しています。

v2-9a0d4c2ca70e4574a98c00aeba4c32cc_hd.png

ヒープオーバーフロー

このシナリオは、最も一般的なエラーメッセージです:

java.lang.OutOfMemoryErrorを:Javaのヒープスペース

理由

図1に示すように、コードが大規模なオブジェクトの割り当て中に存在し得る
2、依然として現在のオブジェクトに対応するために十分な大きさのメモリを見つけることができない、多くのGC後につながる、メモリリークが存在してもよいです。

ソリューション

ラージオブジェクトの割り当て1.確認し、最も可能性の高い大規模な配列の割り当て
jmapのコマンドで2、ヒープメモリダンプダウン、メモリリークの問題がある場合は、チェックを分析するためにマットツールを使用して
重要なのが見つからない場合、3はメモリリーク、-Xmxヒープメモリの使用増加
4を、少し可能性が無視されるように存在し、カスタムファイナライズ可能オブジェクトの数が多い場合は、チェック、フレームの内側に設けてもよいが、その存在の必要性を検討し
、私の男性に歓迎の注意を群れ種類ホ[プログラマ]の、記事が内側に更新されます、仕上げ材が内側になります。

Permanent世代/元オーバーフロースペース

エラーメッセージ:

java.lang.OutOfMemoryErrorを:PermGen spacejava.lang.OutOfMemoryError:メタスペース

理由

永久的な生成は、メソッドエリアHotSot仮想マシン、ストレージクラス情報がロードされ、仮想マシン、定数、静的変数、コンパイルされたコード、等JITの具体的な実現です。

JDK8後、メタスペースは、ローカルメモリ空間を使用して、永久的な発電要素、ならびに変化の他の詳細を置き換えます。

  • 文字列定数は、永久的なヒープ置換に転送します

  • JVMパラメータと永久世代は、関連削除しました

いくつかの理由が考えられます。

1、Java7、頻繁な誤用String.intern()の前に方法
2は、爆発する方法エリアにつながる、動作中にプロキシクラスの多数を生成しないアンインストールすることができ
3、長期実行アプリケーション、再起動なし

いいえJVMプロセスは、一般的に、Tomcatの公式サイトで以下のFAQとして、試運転時に発生する再起動します。

私は、Webアプリケーションを再デプロイするとき、なぜメモリ使用量が増加していますか?Webアプリケーションがメモリリークを持っているからです。一般的な問題は、「PermGen」メモリリークです。クラスローダ(クラスとは、それがロードされたオブジェクト)ので、彼らは)(いくつかの要件が満たされない限り再利用することはできませんが起こります。すべてのこれらのクラスの別のコピーをロードする、彼らはJVMによって永久ヒープ世代に保存されている、としたときに新しいクラスローダを再デプロイが作成されます。これは、最終的にOufOfMemoryErrorsを引き起こす可能性があります。(*)の要件は、このクラスローダによってロードされたすべてのクラスが同時にgc'edすることができなければならないということです。

ソリューション

OOMは、いくつかのソリューションがあるので理由は、比較的簡単です:

1は、小さすぎるスペース又は空間要素の永久的な生成が配置されたかどうかをチェックするために
反射動作確認コードの多くがあるかどうか、2
3は、原因プロキシクラスの反射に多くが生成されているかどうかをチェックすることによりダンプマット
4、拡大ストロークは、JVMを再起動します

V2-b26a29f62e69256653075aa6e05ce75d_hd.png

GCオーバーヘッドの制限を超えました

この例外は、エラーメッセージは比較的まれです。

java.lang.OutOfMemoryError:GC overhead limit exceeded

原因

这个是JDK6新加的错误类型,一般都是堆太小导致的。Sun 官方对此的定义:超过98%的时间用来做GC并且回收了不到2%的堆内存时会抛出此异常。

解决方法

1、检查项目中是否有大量的死循环或有使用大内存的代码,优化代码。

2、添加参数 -XX:-UseGCOverheadLimit  禁用这个检查,其实这个参数解决不了内存问题,只是把错误的信息延后,最终出现 java.lang.OutOfMemoryError: Java heap space。

3、dump内存,检查是否存在内存泄露,如果没有,加大内存。

方法栈溢出

报错信息:

java.lang.OutOfMemoryError : unable to create new native Thread

原因

出现这种异常,基本上都是创建的了大量的线程导致的,以前碰到过一次,通过jstack出来一共8000多个线程。

解决方法

1、通过 -Xss 降低的每个线程栈大小的容量
2、线程总数也受到系统空闲内存和操作系统的限制,检查是否该系统下有此限制:

  • /proc/sys/kernel/pid_max

  • /proc/sys/kernel/thread-max

  • maxuserprocess(ulimit -u)

  • /proc/sys/vm/maxmapcount

非常规溢出

下面这些OOM异常,可能大部分的同学都没有碰到过,但还是需要了解一下

分配超大数组

报错信息 :

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

这种情况一般是由于不合理的数组分配请求导致的,在为数组分配内存之前,JVM 会执行一项检查。要分配的数组在该平台是否可以寻址(addressable),如果不能寻址(addressable)就会抛出这个错误。

解決策は、あなたのコードの大規模な配列があるかどうかをチェックするための場所を作成することです。

v2-7daa361860ef4ee83a6f1748a71a04d4_hd.png

スワップオーバーフロー

エラーメッセージ:

java.lang.OutOfMemoryErrorを:スワップ領域のうち、

これは通常、オペレーティング・システムによって引き起こされ、理由が考えられます。

1、スワップパーティションのサイズ割り当ては不十分です。

2、メモリを消費する他のすべてのプロセス。

ソリューション:

1、他のサービスプロセスを選択的にスワップパーティションのサイズを増加させるために、2を分割し、あるいはインストールされたRAMを増加させることができます

ネイティブメソッドのオーバーフロー

エラーメッセージ:

java.lang.OutOfMemoryErrorを:stack_trace_with_native_method

ランタイムメモリ割り当てに失敗し、そして従来の方法スタックオーバーフローでローカルメソッド、JVMスタックオーバーフローの方法は、コード・レベルで発生し、ローカルメソッドのオーバーフローは、ネイティブメソッドJNIコードまたは場所で起こります。

この異常な確率は非常に低く、唯一のローカル・オペレーティング・システム・ツール、少し大きい難易度によって評価すること、またはより良いあきらめることができます。

遂に

私は、ヨーヨーのような支援への感謝をポイントを集中記事を覚えているようなみんなと共有へようこそ!


おすすめ

転載: blog.51cto.com/14442094/2449151
おすすめ