2

次のものを持つスタンドアロンの Java アプリケーションがあります。

-Xmx1024m -Xms1024m -XX:MaxPermSize=256m -XX:PermSize=256m

時間の経過とともに、ますます多くのメモリを占有し、スワップ(および速度低下)を開始し、最終的に何度も停止しました(OOM +ダンプではなく、停止しただけで、/ var/log/messagesには何もありません)。

私がこれまでに試したこと:

  1. ヒープ ダンプ: ライブ オブジェクトは 1G ヒープから 200 ~ 300Mb を消費します --> ヒープで問題ありません
  2. ライブ スレッドの数はかなり一定です (~60-70) --> スレッド スタックで問題ありません
  3. JMX はある時点で応答を停止します (mb は応答しますが、タイムアウトは低くなります)
  4. スワップをオフにする - より速く死ぬ
  5. strace - すべてが少し遅くなったようです。アプリはまだ死んでおらず、何がそこにあるのかわからない
  6. 上を確認: VIRT は 5.5Gb に、RSS は 3.7Gb に成長
  7. vmstat を確認しています (明らかに、スワップを開始します):

     --------------------------procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
    Sun Jul 22 16:10:26 2012:  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
    Sun Jul 22 16:48:41 2012:  0  0 138652 2502504  40360 706592    1    0   169    21 1047  206 20  1 74  4  0
    . . . 
    Sun Jul 22 18:10:59 2012:  0  0 138648  24816  58600 1609212    0    0   124   669  913 24436 43 22 34  2  0
    Sun Jul 22 19:10:22 2012: 33  1 138644  33304   4960 1107480    0    0   100   536  810 19536 44 22 23 10  0
    Sun Jul 22 20:10:28 2012: 54  1 213916  26928   2864 578832    3  360   100   710  639 12702 43 16 30 11  0
    Sun Jul 22 21:10:43 2012:  0  0 629256  26116   2992 467808   84  176   278  1320 1293 24243 50 19 29  3  0
    Sun Jul 22 22:10:55 2012:  4  0 772168  29136   1240 165900  203   94   435  1188 1278 21851 48 16 33  2  0
    Sun Jul 22 23:10:57 2012:  0  1 2429536  26280   1880 169816 6875 6471  7081  6878 2146 8447 18 37  1 45  0
    
  8. sar は、安定した system% の成長 = スワッピングも示しています。

     15:40:02          CPU     %user     %nice   %system   %iowait    %steal     %idle
     17:40:01          all     51.00      0.00      7.81      3.04      0.00     38.15
     19:40:01          all     48.43      0.00     18.89      2.07      0.00     30.60
     20:40:01          all     43.93      0.00     15.84      5.54      0.00     34.70
     21:40:01          all     46.14      0.00     15.44      6.57      0.00     31.85
     22:40:01          all     44.25      0.00     20.94      5.43      0.00     29.39
     23:40:01          all     18.24      0.00     52.13     21.17      0.00      8.46
     12:40:02          all     22.03      0.00     41.70     15.46      0.00     20.81
    
  9. pmap を確認すると、次の最大の貢献者が得られました。

      000000005416c000 1505760K rwx--    [ anon ]
      00000000b0000000 1310720K rwx--    [ anon ]
      00002aaab9001000 2079748K rwx--    [ anon ]
    
  10. strace によってダンプされたものから pmap から取得したアドレスを関連付けようとしても、一致するものはありませんでした

  11. メモリを追加することは実用的ではありません (問題を後で表示するだけです)。

  12. JVM を切り替えることはできません (env は私たちの管理下にありません)

問題は 、問題の原因を突き止めたり、問題を回避したりするために他に何ができるかということです。

4

3 に答える 3

1

Java および glibc >= 2.10 (Ubuntu >= 10.04、RHEL >= 6 を含む) には既知の問題があります。

解決策は、この環境を設定することです。変数: export MALLOC_ARENA_MAX=4

MALLOC_ARENA_MAX の設定に関する IBM の記事があり ます https://www.ibm.com/developerworks/community/blogs/kevgrig/entry/linux_glibc_2_10_rhel_6_malloc_may_show_excessive_virtual_memory_usage?lang=en

このブログ投稿は言う

常駐メモリは、メモリ リークやメモリの断片化と同様の方法でクリープすることが知られています。

その他の参照については、Google または SO で MALLOC_ARENA_MAX を検索してください。

割り当てられたメモリの断片化が少なくなるように最適化するために、他の malloc オプションも調整することをお勧めします。

# tune glibc memory allocation, optimize for low fragmentation
# limit the number of arenas
export MALLOC_ARENA_MAX=2
# disable dynamic mmap threshold, see M_MMAP_THRESHOLD in "man mallopt"
export MALLOC_MMAP_THRESHOLD_=131072
export MALLOC_TRIM_THRESHOLD_=131072
export MALLOC_TOP_PAD_=131072
export MALLOC_MMAP_MAX_=65536
于 2015-03-09T04:24:51.363 に答える
1

問題は、接続されているプロファイラー ライブラリにありました。CPU 呼び出し/割り当てサイトが記録されたため、それを保存するためにメモリが必要でした。

だから、ここの人的要因:)

于 2012-07-25T14:18:03.133 に答える
1

JVM 内の何かが「無制限」の量の非ヒープ メモリを使用しています。考えられる候補は次のとおりです。

  • スレッドスタック。
  • 一部のネイティブ コード ライブラリによって割り当てられたネイティブ ヒープ。
  • メモリ マップト ファイル。

最初の可能性は、スレッド スタック ダンプを取得したときに、多数の (そして増加している) スレッドとして表示されます。(ちょっと調べて…いい?)

アプリケーション(またはそれが使用するサードパーティライブラリ)がネイティブライブラリを使用しない場合、(おそらく)削除できる2番目のもの。

アプリケーション (またはそれが使用するサード パーツ ライブラリ) がメモリ マップ ファイルを使用しない場合は、3 番目のものを削除できます。


OOME が表示されない理由は、JVM が Linux OOM キラーによって強制終了されているためだと思います。JVM がネイティブ コードで救済されている可能性もあります (たとえば、malloc の失敗が適切に処理されていないため)。

于 2012-07-23T06:15:26.097 に答える