web-dev-qa-db-ja.com

Java:非ヒープメモリ分析

非ヒープメモリが常に増加しているという問題があります。そのため、私たちはjee(Java8)-webappを3日ごとに再起動する必要があります(ここのスクリーンショットで見ることができるように non-heap-およびheap-memoryからのスクリーンショット

私はすでに、その非ヒープを埋めるものを見つけることを試みました。しかし、非ヒープダンプを作成するためのツールを見つけることができませんでした。どのようにしてどの要素が成長しているのかを知るために、それをどのように調査すればよいか考えていますか?

Javaバージョン

Java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

Tomcatバージョン

Apache Tomcat Version 7.0.59
13
stefa ng

MemoryPoolMXBean によって提供される非ヒープメモリ使用量は、次のメモリプールをカウントします。

  • メタスペース
  • 圧縮されたクラススペース
  • コードキャッシュ

言い換えると、標準の非ヒープメモリ統計には、コンパイルされたメソッドとロードされたクラスによって占有されているスペースが含まれます。ほとんどの場合、ヒープ以外のメモリ使用量の増加は、クラスローダーのリークを示しています。

使用する

  • jmap -clstats PIDはクラスローダーの統計をダンプします。
  • jcmd PID GC.class_statsは、ロードされた各クラスのメモリ使用量に関する詳細情報を出力します。後者には-XX:+UnlockDiagnosticVMOptionsが必要です。
6
apangin

@apanginが指摘しているように、時間の経過とともにより多くのメタスペースを使用しているように見えます。これは通常、より多くのクラスをロードしていることを意味します。ロードされているクラスとコンパイルされているメソッドを記録し、本番環境で継続的に実行される量を制限しようとします。継続的にコードを生成しているがクリーンアップしていないライブラリがある可能性があります。ここで、作成されているクラスを確認すると、どのクラスかに関するヒントが得られます。


ネイティブの非ヒープメモリ用。

Linuxのメモリマッピングは/proc/{pid}/mapsで確認できます。これにより、使用されている仮想メモリの量がわかります。

これが原因かどうかを判断する必要があります

  • スレッドまたはソケットの数の増加
  • 使用されている直接ByteBuffers。
  • ネイティブ/ダイレクトメモリを使用しているサードパーティのライブラリ。

グラフを見ると、ヒープを減らして最大ダイレクトメモリを増やし、再起動時間を1週間以上に延ばすことができますが、より良い解決策は原因を解決することです。

0
Peter Lawrey

Java 8の場合、クラスメタデータはMetaspaceと呼ばれる非ヒープメモリセクションにあります(PermGenではありません)非ヒープメモリが主にMetaspaceによって消費されている場合、 jstat でそれを把握できます。

ヒープ以外のメモリを分析するための一般的なツールではありません。しかし、それでもあなたの場合には役立つかもしれません。

0
Codo