JavaプロセスがLinuxで実行されているためにメモリがどこに移動したかを特定しようとしています。pmap-xを使用してメモリの動作を正確に確認するように誰かが提案しました。
出力は非常に長くなりますが、基本的には、これの繰り返しがこの部分の繰り返しになります。
00007fbf75f6a000 1016 - - - rwx-- [ anon ]
00007fbf76068000 12 - - - ----- [ anon ]
これはどういう意味ですか?なぜこれほど多くのエントリがあるのですか(4000以上)?
Anonブロックは、mallocまたはmmapによって割り当てられた「大きな」ブロックです。マンページを参照してください。そのため、それらはJavaヒープとは何の関係もありません(ヒープ全体がそのようなブロックにのみ格納される必要があるという事実を除いて)。
私の経験では、スレッドスタックもanonブロックを使用しています。すべて同じサイズの多くのanonブロックがあり、そのサイズが512k〜4Mbである場合(以下の例は、実行中のTomcatプロセスで数十回繰り返されます)、それが原因である可能性があります。プログラムによっては、これらの数十まであるかもしれません。何千も表示されている場合は、スレッド処理に問題があることを意味します。
b089f000 504K rwx-- [ anon ]
b091d000 12K ----- [ anon ]
b0920000 504K rwx-- [ anon ]
b099e000 12K ----- [ anon ]
b09a1000 504K rwx-- [ anon ]
b0a1f000 12K ----- [ anon ]
しかし、それは疑問を残します:なぜpmapを使用してJavaメモリの問題を診断するのですか?
Eclipse MATを使用します(JavaヒープでネイティブヒープではなくOutOfMemoryExceptionsを取得する場合))。
そのパターンはスレッドリークで以前に見たことがあります。スレッドをプールしようとしているコードがあるのに、どういうわけかスレッドがめちゃくちゃになってリークしている場合、pmapでそのようなパターンが得られます。
メモリの各ビットは、スレッドの最小スタックサイズだと思います。確かに、私たちの場合、ヒープとは何の関係もありませんでした。
OSの制限に達したときでも、割り当て超過ではないヒープを分析したときでも、OutOfMemoryErrorsが発生しました。
このような問題が発生したときpmap [pid] | grep -c 12K
は、使用中のスレッドの数であることが判明しました。