2017-02-14 6 views
2

Tomcatで実行しているウェブアプリケーションの最大ヒープサイズが8GBに設定されています。完全なGCを実行させる原因は何ですか?

以下は私のVMの引数です。

export CATALINA_OPTS="$CATALINA_OPTS -Xms512m -Xmx8192m -XX:+UseConcMarkSweepGC" 

何のユーザーがアプリにログインしていない場合は、(ガベージコレクションの後に存在する)非洗浄可能なメモリが(約1GB)、非常に低いです。

この状況で、jconsoleを使用してメモリの増加パターンを観察すると、約4GBの一定のメモリが増加し、ガベージコレクタが実行され、メモリが約1GBに再び低下します。このパターンは、ユーザーがログインしなくても続きます。

GCデータを記録すると、次のような状態になります。

2017-02-14T15:30:44.553+0530: 591.922: [GC (Allocation Failure) [PSYoungGen: 1501051K->631966K(1833472K)] 2392189K->1523112K(3030016K), 1.5100144 secs] [Times: user=1.49 sys=0.01, real=1.51 secs] 
2017-02-14T15:31:20.335+0530: 627.705: [GC (Allocation Failure) [PSYoungGen: 1553054K->595007K(1842176K)] 2444200K->1570521K(3038720K), 1.3050284 secs] [Times: user=1.27 sys=0.04, real=1.31 secs] 
2017-02-14T15:33:33.682+0530: 761.052: [GC (Allocation Failure) [PSYoungGen: 1516095K->556800K(1842176K)] 2491609K->1596474K(3038720K), 1.6957154 secs] [Times: user=1.67 sys=0.03, real=1.69 secs] 
2017-02-14T15:33:35.378+0530: 762.748: [Full GC (Ergonomics) [PSYoungGen: 556800K->365446K(1842176K)] [ParOldGen: 1039673K->1196476K(2018304K)] 1596474K->1561923K(3860480K), [Metaspace: 70472K->70472K(1114112K)], 11.2779843 secs] [Times: user=11.13 sys=0.09, real=11.28 secs] 
2017-02-14T15:34:56.232+0530: 843.602: [GC (Allocation Failure) [PSYoungGen: 1286534K->216613K(1842176K)] 2483011K->1609875K(3860480K), 1.4938761 secs] [Times: user=1.45 sys=0.05, real=1.50 secs] 

それが分かるように、時々フルGCマイナーGCに比べてかなりの時間(11秒)を取った、実行され(約1秒)。

GC中に他のすべてのスレッドが中断されるため、ユーザーがFull GC中にWebアプリケーションにアクセスしようとすると、サーバーは応答しません。

私が知りたかったのは、このフルGCを引き起こすのは何ですか?ログによると、マイナーなGCイベントは割り当て失敗によるもので、Full GCはErgonomicsによるものです。これは何を意味するのでしょうか?

この場合、Full GCが起きないようにする方法はありますか?フリーなヒープスペースが残っています。マイナーGCのためにメモリが大幅に削減されるまでFull GCを遅らせる必要があります。

+1

使用しているすべてのGC関連VMオプション(Xms、MaxGCPauseMillis、コレクタなど)とサーバーの物理メモリを追加してください。休止時間を短くしたい場合は、休止時間が短く長くなるので、完全なgcsを遅らせる方法はありません。だから私のヒープはあなたが達成したい目標(プラスあなたが間違ったコレクションアルゴリズムを使用している)のために大きすぎるように構成されているようです。 –

+0

@ piet.t、vmオプションが質問 –

+0

に追加されました。アプリケーションがコードのどこかで明示的な 'System.gc()'呼び出しを行っている可能性があります。私は、CMSコレクタがちょっと狂っているのを見て、 'System.gc()'の呼び出しの後で常に世界的に完全なGCを実行しています。 GCが '-XX:+ DisableExplicitGC' JVMオプションを通してそのような呼び出しを無視するようにすることができます。 –

答えて

0

主な問題(ガベージコレクションに費やされた時間が長すぎたためにサーバーが停止する)に対処すると、何らかの理由で間違ったガベージコレクタが使用された可能性があります。ガベージコレクションチューニングについては、hereと記載されています。 Garbage-First collectorを使用すると、受け入れ可能なポーズをいつでも設定することができます(デフォルトは200ミリ秒で、サーバーにとって大きな問題ではありません)。

0

私はあなたにParallel Collectorリンクを指摘します。 「人間工学」は、コレクタをアプリケーションの特定の動作で自動チューニングする方法です。

ほとんどの場合、オートチューニングは問題ありません。あなたのケースでは、それはあまりにも長いGCで終わるようです。コレクターのパラメーターを自分で調整して修正することができます。文書を引用

最大ガベージコレクションの休止時間

最大休止時間の目標は、コマンドラインオプション-XXで指定されている:MaxGCPauseMillis =。これは、ミリ秒以下の休止時間が必要であるというヒントとして解釈されます。デフォルトでは、最大休止時間の目標はありません。休止時間の目標が指定されている場合、ヒープサイズやその他のガベージコレクションに関するパラメータは、ガベージコレクションの一時停止を指定された値よりも短く保つために調整されます。これらの調整によって、アプリケーションの全体的なスループットがガベージコレクタによって低下する可能性があり、目的の休止時間の目標を常に満たすことができません。

スループット

スループット目標は、時間的に測定される(印加時間と呼ぶ)ガベージコレクションの外に費やした時間に対するガベージコレクションをやって過ごしました。ゴールはコマンドラインオプション-XX:GCTimeRatio =で指定され、アプリケーション時間に対するガベージコレクション時間の比率を1 /(1 +)に設定します。

たとえば、-XX:GCTimeRatio = 19は、ガベージコレクションの合計時間の1/20または5%という目標を設定します。デフォルト値は99で、ガベージコレクションの時間の1%を目標としています。

フットプリント

最大ヒープ・フットプリントは、オプション-Xmxを使用して指定されています。さらに、コレクタには、他の目標が満たされている限り、ヒープのサイズを最小限に抑えるという暗黙の目標があります。

+0

-XX:MaxGCPauseMillisは私にとっては良い選択ですが、完全なGCにかかる時間を最小限に抑えることができますか?私の場合、マイナーGCはかなり速く実行されますが、フルGCは約10倍の時間がかかります。私は、-XX:MaxGCPauseMillisがこれを約1秒に短縮できるかどうか疑問を持っています。 –

+0

@LahiruChandimaもちろん、設定された時間を尊重するのが最善ですが、それは単なるヒントです。 GCをカスタマイズした後も引き続き問題が発生している場合は、ゴミに対して非常に多くのオブジェクトが存在する理由と、それがより小さい時間枠では実行できない理由を調査する必要があります。 –

+0

-XX:MaxGCPauseMillisを付けて確認します。実際には、完全なGCの期間が長いのは、オブジェクト数が多いためではないと思います。 jconsoleで観察したように、マイナーGCが発生すると、2秒以内に約3GBのガベージオブジェクトが削除されます。 –

関連する問題