-1

8GB のメモリと 4 つの CPU を搭載したマシンで Java アプリケーションを実行しています。しかし、ストレステストでアプリケーションを長時間実行した後、メモリが完全にいっぱいになり、gc サイクルが完了するまでに時間がかかるように見えるため、ガベージコレクターの問題が観察されますが、考えられる原因とその解決策を理解できません。リクエストが完了するまでの平均レイテンシーに大きな違いはありません。しかし、多くのスレッドを同時に処理することはできません。

次のパラメータでアプリケーションを開始しました

-Xms4096M -Xmx4096M 
-XX:MaxPermSize=512M 
-XX:PermSize=512m 
-XX:+UseConcMarkSweepGC 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:+PrintGCTimeStamps 
-XX:+PrintGCDetails 
-XX:+PrintGCApplicationStoppedTime 
-XX:+PrintGCApplicationConcurrentTime 
-XX:+PrintHeapAtGC 
-Xloggc:/root/tomcat_logs/gc_logs.log

top コマンドの出力

top - 11:24:03 up 44 days, 23:45,  1 user,  load average: 0.39, 0.47, 0.65
Tasks: 158 total,   1 running, 157 sleeping,   0 stopped,   0 zombie
Cpu(s): 18.8%us,  2.1%sy,  0.0%ni, 64.2%id, 12.9%wa,  0.2%hi,  1.8%si,  0.0%st
Mem:   7672012k total,  7270396k used,   401616k free,   238468k buffers
Swap:  5238776k total,    34584k used,  5204192k free,  2390820k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                           
15811 root      20   0 7919m 4.1g   9m S 101.1 55.9   4134:37 java 

メモリがいっぱいになった後のサンプル GC ログ

{Heap before GC invocations=193901 (full 4):
 par new generation   total 306688K, used 274312K [0x00000006c0000000, 0x00000006d4cc0000, 0x00000006d4cc0000)
  eden space 272640K, 100% used [0x00000006c0000000, 0x00000006d0a40000, 0x00000006d0a40000)
  from space 34048K,   4% used [0x00000006d2b80000, 0x00000006d2d222c8, 0x00000006d4cc0000)
  to   space 34048K,   0% used [0x00000006d0a40000, 0x00000006d0a40000, 0x00000006d2b80000)
 concurrent mark-sweep generation total 3853568K, used 687930K [0x00000006d4cc0000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 58528K, capacity 59902K, committed 61732K, reserved 1103872K
  class space    used 6866K, capacity 7109K, committed 7464K, reserved 1048576K
89974.407: [GC (Allocation Failure) 89974.407: [ParNew: 274312K->1655K(306688K), 0.0101861 secs] 962243K->689622K(4160256K), 0.0104010 secs] [Times: user=0.04 sys=0.00, real=0.01 secs] 
Heap after GC invocations=193902 (full 4):
 par new generation   total 306688K, used 1655K [0x00000006c0000000, 0x00000006d4cc0000, 0x00000006d4cc0000)
  eden space 272640K,   0% used [0x00000006c0000000, 0x00000006c0000000, 0x00000006d0a40000)
  from space 34048K,   4% used [0x00000006d0a40000, 0x00000006d0bdded0, 0x00000006d2b80000)
  to   space 34048K,   0% used [0x00000006d2b80000, 0x00000006d2b80000, 0x00000006d4cc0000)
 concurrent mark-sweep generation total 3853568K, used 687966K [0x00000006d4cc0000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 58528K, capacity 59902K, committed 61732K, reserved 1103872K
  class space    used 6866K, capacity 7109K, committed 7464K, reserved 1048576K
}
89974.418: Total time for which application threads were stopped: 0.0127352 seconds
89974.988: Application time: 0.5703336 seconds

なぜメモリがいっぱいになるのか、それを克服してより高い負荷でアプリを長期間実行できるようにするために何ができるのかという結論に達したかったのです。そうするのを手伝ってください。

4

2 に答える 2

0

基本的に、メモリリークの可能性に直面しています。YourKIt (または選択したプロファイラー) を使用して、アプリケーションを実行し、やがて定期的にガベージ コレクションを強制します。次に、gc を強制してもまだ蓄積されているオブジェクトを確認します。時間のかかる作業になる可能性がありますが、最終的には報われます。

考えられる原因は、ClassLoader のリーク、弱い参照、不適切に実装されたキャッシングなどです。

于 2016-02-27T06:06:11.993 に答える