2016-10-26 17 views
3

私たちはJavaでRTシステムを実行しています。比較的大きなヒープ(100 + GB)を頻繁に使用し、メッセージキューからの要求を処理します。 SLAを満たすには、各要求を高速に処理する必要があります(< 100ms)。リアルタイムシステムでのJavaガベージコレクションの制御

GCがリクエスト(200 + ms)中に世界を停止させて失敗することがよくあるため、GC関連の深刻な問題が発生しています。

GCの合理的な知識を持つ開発者の一人は、GCパラメータの調整やさまざまなGCの試行にかなりの時間を費やしました。数日後、彼は「遺伝的アルゴリズムによって進化した」という冗談を呼んでいるいくつかのパラメータを思いついた。 GCの休止時間は短縮されますが、まだSLAの要件を満たしていません。

私が探しています解決策は、にある次の要求をとる前に、GCからのコードのいくつかの重要な部分を保護し、要求が終了した後、それが必要としてGCが同じくらい仕事をさせて、。私たちには数人の労働者がいて、ごみ収集労働者はしばらくの間は依頼を要求しないので、要求以外の一時停止は問題ありません。

私は、愚かな醜いいくつかのアイデアを持っているし、おそらく動作していない、うまくいけば、彼らは問題説明:

  • 時々にいくつかの作業を行うためにGCのために祈って、受信スレッドでThread.sleep()を呼び出しをそれが支援するため、その間、
  • 起動System.gc()または要求間のRuntime.gc()は、再び絶望的https://stackoverflow.com/a/6915221/1137187のようなハックのパターンと全く
  • メス、コードを祈ります。

最後に重要なのは、私たちは低予算のスタートアップであり、Zing®などの商用ソリューションはオプションではないということです。私たちは非商用ソリューションを探しています。

アイデア?私たちはコードをC++に書き直しました(最初は解でなくGCが問題であるかもしれません)が、コードベースはあまりにも大きすぎて実行できませんでした。

+0

「リアルタイム」という言葉を聞いても、Javaは確かに最初の言語ではありません.Javaが選ばれたことを考えると、巨大なヒープの必要性はうまくいかないようです。 –

+2

いずれにしても、実際には、長時間実行されるプロセスでは、(1)生成されるゴミの量を減らし、(2)収集するためにゴミを速くするといった、GC問題に対する2つの一般的なアプローチがあります。完全なGCが高価ですが頻繁でない場合は、ヒープサイズを大幅に減らす方法があります。それはより頻繁なGCを必要としますが、収集するゴミがそれほど多くないので、それぞれがより速くなければなりません。また、プロセスの全寿命にわたって保持されない限り、世代別GCが収集するにはより高価な長命のオブジェクトを避けてください。 –

+2

また、一時的なオブジェクトにも注意してください。多くのオブジェクトを作成して破棄するよりも、Javaコーディング担当者がGCに頼るのは珍しいことではありません。彼らはそうしていることを認識していないかもしれません。たとえば、文字列の連結と自動ボクシングが貢献できます。プリミティブにはGCコストはなく、経験則として、低レベルのAPIはゴミを少なくします。 –

答えて

1

別のJVMを使用しますか? Azulはそのようなケースを処理できると主張しています。 Redhatは同様の目標を念頭に置いてopenjdkにshenandoahを寄稿していますので、商用ソリューションが必要ない場合は実験的なビルドを試すことができます。

リアルタイムアプリケーションに焦点を当てた他のJVMもありますが、私が理解しているように、より小さいシステムではより難しいリアルタイム要件に焦点を当てています。

事前割り当てオブジェクトまたは適用可能な場合はよりコンパクトなデータ表現を使用することによって、オブジェクト割り当てを大幅に減らすことができます(アプリケーションのプロファイリング)。新しい世代のサイズを同じに保ちながら配分圧力を下げると、コレクションごとの死亡率が増加し、若いコレクションのスピードを上げることになります。

メモリ帯域幅を最大限に活用するためにハードウェアを選択することも役立ちます。-XX:+ExplicitGCInvokesConcurrentと組み合わせたとき

呼び出しにSystem.gc()または要求間のRuntime.gcは()、再び絶望的にそれ以外の場合はトリガし、

このかもしれないが、それは助けるために仕事を祈りますCMSまたはG1(私はあなたがそれらの1つを使用していると仮定している)とのシングルスレッドSTWコレクション。しかし、そのアプローチは脆弱であるように見え、多くのチューニングと監視が必要です。

+0

私は 'System.gc()' + '-XX:+ ExplicitGCInvokesConcurrent'への試みはほとんどしませんでしたが、実際にはうまくいきません。主に' System.gc () 'が数分間実行されます。完全なGCを実行することはオプションのようではないようです。そして、はい、私たちはCMSとG1の両方を試していました。 他に何も助けなければ、代替JVMとプロファイリング+リファクタリングを試さなければなりません。しかし、それについてもっと考えると、私がJVMにコレクションを行う時期を伝えることは、私の場合に必要とされるものであると確信しています。 GCパラメータを調整することで、JVMに追加情報を与えることなく、原則として私の問題を解決することはできません。 – Tregoreg

+0

さて、休止時間は200msで、SLAは<100msです。したがって、2-3の要素を絞ることができれば、範囲内にあるようです。 – the8472

関連する問題