LMAXのチームがなぜJavaを使用し、GCを避けるためにアーキテクチャを設計したのですか?


24

LMAXのチームがJavaでLMAX Disruptorを設計したのに、GCの使用を最小限に抑えることがすべての設計ポイントであるのはなぜですか?GCを実行したくない場合、ガベージコレクションされた言語を使用するのはなぜですか?

彼らの最適化、ハードウェアの知識のレベル、そして彼らが置いた思考はただ素晴らしいですが、なぜJavaなのでしょうか?

私はJavaなどに反対ではありませんが、なぜGC言語なのですか?DのようなものやGCを使用しない他の言語を使用して、効率的なコードを使用できるのはなぜですか?チームはJavaに最も精通しているのでしょうか、それともJavaには私には見られない独自の利点がありますか?

手動のメモリ管理でDを使用して開発するとしますが、違いは何でしょうか?低レベル(既にある)を考える必要がありますが、システムがネイティブであるため、システムから最高のパフォーマンスを引き出すことができます。


6
私はこのプロジェクトについてほとんど知りませんが、他の人が構築できるフレームワークのようです。そして、あなたは(Javaでコードを他の人を許すとメリットを享受して)Javaで、その後、あなたはDにそれを書かれているだろう場合よりもはるかに大きく、「顧客基盤」を持っているだろうという書き込みに管理している場合
ヨアヒム・ザウアー

6
@kadaj:消費者がパブリックであるか内部であるかは実際には関係ありません。広く知られている言語でアクセス可能にすれば、内部開発にとってもより便利になります。(仮想の)議論を「誰もがJavaを知っているだけでなくDも知っていると仮定して...」で始めると、おそらく何かが足りないでしょう。
ヨアヒムザウアー

6
一部の人々は、あらゆる種類の問題にハンマーを使用することを好みます。プレーニングしたい荒いエッジを手に入れ、ハンマーで滑らかになるまで打ちます。打ち込む必要のあるネジを手に入れ、ハンマーで打ち込みます。サンディングが必要な繊細な飾りを手に入れ、ハンマーで打ち、「吸う」ために飾りを責めます。既存のナレッジベースの場合のみ、CまたはC ++がDよりも優れた選択でした。TBHの例としてDを育てた理由がわからない。
gbjbaanb

2
@gbjbaanb Dは、ガベージコレクションを提供するため(高レベルの抽象化が必要であり、メモリをいじるのが脳にとって難しい場合)、Cスタイルのmallocおよびfreeを使用して手動でメモリ管理できるためです。DはARCを備えたObjective-Cに似ていますが(実際のGCはありません)、それよりも優れています。しかし、そうです、C / C ++はその法案に適合します。

4
D Dは実際にはあまり使用されていませんが、DはJavaやC#などで見られると思われる高レベルの構造を提供しますが、(少なくとも古いスタイルの)C ++ではそうではありません。マネージドとアンマネージドを混在させることができます。これは、私が知っている唯一の言語です。したがって、Dは単なるペットの選択ではなく、GCに関する元の質問と一致する目標を持つものです。
Jトラナ

回答:


20

パフォーマンス最適化すること安全性を完全にオフにすることには大きな違いがあるため

GCの数を減らすことにより、フレームワークの応答性が向上し、(おそらく)より速く実行できるようになります。現在、ガベージコレクタの最適化は、ガベージコレクションを行わないという意味ではありません。それは彼らがあまり頻繁にそれをしないことを意味し、彼らがそれをするとき、それは本当に速く走ります。これらの種類の最適化には以下が含まれます。

  1. 小さなスローアウェイオブジェクトを使用して、サバイバースペースに移動する(つまり、少なくとも1つのガベージコレクションを生き残った)オブジェクトの数を最小限に抑える。サバイバー空間に移動したオブジェクトは収集が難しく、ここでのガベージコレクションはJVM全体の凍結を意味する場合があります。
  2. 最初からあまりにも多くのオブジェクトを割り当てないでください。若い世代のオブジェクトは割り当てや収集が非常に安価であるため、注意しないとこれは逆効果になります。
  3. 新しいオブジェクトが古いオブジェクトを指していることを確認し(逆ではない)、若いオブジェクトを簡単に収集できるようにします。

パフォーマンスを調整するときは、頻繁に実行されないコードを無視しながら、通常は非常に具体的な「ホットスポット」を調整します。Javaでそれを行う場合、ガベージコレクターにこれらの暗いコーナーを処理させることができます(大きな違いは生じないため)が、タイトループで実行される領域に対して非常に慎重に最適化します。したがって、最適化する場所としない場所を選択できるため、重要な場所に努力を集中できます。


ガベージコレクションを完全にオフにすると、選択できなくなります。これまで、すべてのオブジェクトを手動で廃棄する必要があります。そのメソッドは1日に1回しか呼び出されませんか?Javaでは、パフォーマンスへの影響は無視できるため、そのままにすることができます(完全なGCを毎月発生させてもかまいません)。C ++では、まだリソースがリークしているため、そのあいまいなメソッドにも注意する必要があります。したがって、アプリケーションのすべての部分でリソース管理の料金を支払う必要がありますが、Javaでは集中できます。


しかし、それはさらに悪化します。

バグがある場合は、満月の月曜日にのみアクセスされるアプリケーションの暗いコーナーで言ってみましょう。Javaには強力な安全性保証があります。「未定義の動作」はほとんどありません。間違ったものを使用すると、例外がスローされ、プログラムが停止し、データの破損は発生しません。だから、気づかないうちに何も悪いことは起こらないと確信しています。

しかし、Dのようなものでは、不正なポインタアクセスやバッファオーバーフローが発生する可能性があり、メモリを破損する可能性がありますが、プログラムは認識せず(安全をオフにしたことを覚えていますか?)データ、およびいくつかの非常に厄介なことを実行してデータを破損しますが、あなたは知らない、そしてより多くの破損が発生するにつれて、データはますます間違って、それから突然壊れて、それは人生に不可欠なアプリケーションにありました、そしてその指を、いくつかのエラーは、ロケットの計算に起こった、そしてそれは仕事、そしてロケット爆発、と誰かのダイスをしないように、そしてあなたの会社は、すべての新聞のフロントページにあり、あなたの上司のポイントあなたあなたが「と言っていますパフォーマンスを最適化するためにDを使用することを提案したエンジニアが、なぜ安全性を考えなかったのですか?「そして、それはあなたのせいです。あなたはパフォーマンスへのあなたの愚かな試みでそれらの人々を殺しました。


わかりました、ほとんどの場合、それはそれよりも劇的ではありません。しかし、ビジネスクリティカルなアプリケーションやGPSアプリだけでなく、たとえば政府のヘルスケアWebサイトでも、バグがあるとかなりマイナスの結果をもたらす可能性があります。それらを完全に防ぐか、発生したときにフェイルファーストする言語を使用することは、通常非常に良い考えです。

安全をオフにするのにはコストがかかります。ネイティブになることは必ずしも意味をなさない。時には、少しでも安全な言語を最適化する方がはるかに簡単で安全な場合があります。多くの場合の正確性と安全性は、GCを完全に排除することによって廃棄される数ナノ秒に勝ります。そのような状況ではDisruptor 使用できるため、LMAX-Exchangeが適切な呼び出しを行ったと思います。

しかし、特にDはどうですか?暗いコーナーが必要な場合はGCがあり、SafeDサブセット(編集前には知りませんでした)は未定義の動作を削除します(使用することを忘れない場合!)。

まあその場合、それは単純な成熟度の問題です。Javaエコシステムは、適切に作成されたツールと成熟したライブラリでいっぱいです(開発に適しています)。Dよりも多くの開発者がJavaを知っています(メンテナンスの方が良い)。金融アプリケーションのように重要な何かのために、あまり人気のない新しい言語を選ぶのは良い考えではなかったでしょう。あまり知られていない言語では、問題がある場合、あなたを助けることができるものはほとんどありません。あなたが見つけるライブラリは、より少ない人々にさらされているため、より多くのバグを持つ傾向があります。

ですから、私の最後のポイントはまだ保持しています。あなたが悲惨な結果を伴う問題を避けたいなら、安全な選択を固守してください。Dの人生のこの時点で、顧客は狂ったリスクを取る準備ができている小さな新興企業です。問題に数百万の費用がかかる場合は、イノベーションの鐘型曲線にとどまることをお勧めします。


2
元の投稿では特にDを呼び出しています。実際には、選択の粒度に関して、C ++とDにはかなり大きな違いがあります。SafeDサブセットで完全に管理することを選択した場合でも、収集とタイミングの特定の側面(有効化/無効化、収集、最小化)をより詳細に制御できると思います。メモリ管理のためのDigital Marsの戦略をご覧
Jトラナ

2
lmaxは、Javaが提供する安全性のいくつかを意図的に回避します
James

これは、Javaがミッションクリティカルなソフトウェア用にライセンスされていないことを除いて、すばらしい答えです。核反応炉をお持ちの場合、JavaではなくC ++で記述されます。これにより、「安全性」の側面がすべて失われます。
gbjbaanb

@gbjbaanb、[引用が必要]。私が見た信頼性の基準/ガイドラインは、最初に他の言語を支持してC / C ++を避けることを推奨しています。そして、それらに入る場合は、非常に制限されたバージョンの言語(MISRAなど)を使用します。そして、あなたが制限を受け入れると、なぜ他の言語でも同じことができないのかわかりません。RESTRICTIONSセクションでJava Licenceの「原子力施設ではない」ということを考えていた場合、それは少し前に変更されたように見えますが、代わりに「注意してください、私たちの責任ではない」に似たものを言っています。それでも、(...)
hmijail

(...)元の文言はgccおよびclangのライセンスのようでした。特定の目的を保証するものではありません。したがって、信頼性を必要とするものには使用せず、代わりに特定の言語(Ada?)に到達しない場合は、認定コンパイラを使用する必要があります。
hmijail

4

Javaで書かれている理由は、彼らが社内でJavaの専門知識を持っているためで、おそらくC ++がC ++ 0x / 11と一緒に行動する前に書かれたからだと思われます(まだ開発中です)。

それらのコードは実際には名前だけでJavaであり、sun.misc.Unsafeをかなり使用していますが、これはJavaのポイントを打ち負かし、安全性が与えられると思われます。DisruptorのC ++ポートを作成しましたが、出荷されているJavaコードよりもパフォーマンスが優れています(JVMのチューニングに多くの時間を費やしていません)。

とはいえ、ディスラプターが従う原則は言語固有ではありません。たとえば、ヒープを割り当てたり解放したりする低遅延のC ++コードを期待しないでください。


実装を指摘できますか?より高いパフォーマンスを主張するよりもこのような再実装がいくつか見られましたが、両方とも単純化されていました。ディスラプターの著者自身がGoogleグループスレッドで、Javaバージョンのパラメーターをハードワイヤリングすることでパフォーマンスを改善できると述べました。
hmijail

4

この質問は、事実として誤った前提を述べてから、その誤った前提について議論します。

これを掘り下げてみましょう。「GCの使用を最小限に抑えるためのすべての設計ポイント」-単に真実ではありません。ディスラプターの革新は、GCとはほとんど関係ありません。破壊器が機能するのは、その設計が最新のコンピューターの動作を巧みに考慮しているためです。議論については、Cliff Clickの講演http://www.azulsystems.com/events/javaone_2009/session/2009_J1_HardwareCrashCourse.pdf参照してください

LMaxがAzulの顧客であることはよく知られています。Azul GCの場合、175GBのヒープであっても、問題ではないことを直接知っています。


これには一粒の真実があります。大規模な収集を避けるために、VMを毎晩再起動します。とにかく、Martin Fowlerが書いたもので、彼はダミーではありません。martinfowler.com/articles/lmax.html
ジミージェームズ

2
そうでもない。以前は、5分の取引ギャップで毎晩手動GCをトリガーし、それが1日で唯一の主要なGCになるように調整していました。それはAzul Zingによって冗長になりました。(出典:最近までLMAXで働いていました)
トムジョンソン

@TomJohnson内部スクープを取得するのが大好き。マーティン・ファウラーの説明が間違っていると言っていますか?ソリューションは時間とともに進化する可能性はありますか?
ジミージェームズ

2
私は彼がいくつかの小さな詳細について正確に正しくなかったと言っています。システムを毎日バウンスすることはありませんでしたが、1日の終わりに何らかのクリーンアップを行いました。
トムジョンソン

3

彼らは低レベル考えなければなりません

上記はあなたが探している答えの半分になります。LMAXブログと同じように、推論を完了するための半分を見つけることができます。

非常に効率的ですが、簡単に台無しになるため、多くのエラーが発生する可能性があります...

LMAX開発者が認めているように、そのようなコードは、たとえJavaであっても、開発、理解、デバッグが非常に難しい場合があります。低レベルのプログラミング言語に関するウィキペディアの記事で指摘されているように、現在よりもさらに低いレベルに進むと、この問題が悪化するだけです

低レベル言語で書かれたプログラムは、非常に高速に実行でき、非常に小さなメモリフットプリントで実行できます。高水準言語での同等のプログラムは、より重いものになります。低レベル言語は単純ですが、覚えておく必要のある多くの技術的な詳細のために、使いにくいと考えられています

比較すると、高レベルのプログラミング言語は、プログラムの仕様からコンピューターアーキテクチャの実行セマンティクスを分離し、開発簡素化します...


3

Javaを構文言語として使用し、そのJDKライブラリを使用しない場合、コンパイルされた非GC言語と同じくらい高速になります。GCはリアルタイムシステムには適していませんが、Javaでゴミを残さないシステムを開発することは可能です。その結果、GCはトリガーされません。

Java言語とプラットフォームにはC / C ++よりも多くの利点があると信じており、超低遅延のJavaコンポーネントを開発およびベンチマークして、それを証明しています。この記事では、GCを使用しないJava開発の手法について説明します。


2
リアルタイムシステムに適したガベージコレクタがあります。JVMのデフォルトコレクターはそうではないかもしれませんが、それは一般的なGCがリアルタイムに適していないという意味ではありません。ただしmalloc/free、断片化のために割り当て時間が制限されないため、プレーンはリアルタイムにも適していません。
ドーバル14年

1
ウォームアップ後に割り当てが発生しないように、すべてに高速オブジェクトプールを使用することを推奨します。
rdalmeida 14年

2

LMAXは、高性能なスレッド間メッセージングライブラリです。

有用であるためには、他の誰かが各スレッドに有用な仕事をさせるコードを書かなければなりません。コードがJavaまたはC#である可能性が最も高いことを考えると、それらとうまくインターフェースする言語の選択はほとんどありません。

CまたはC ++を使用するのは、スレッドモデルが定義されていないため、ユーザーを単一のOSに制限する場合を除き、適切なオプションではありません。

最近のJavaは多くのソフトウェア開発の標準であるため、特に理由がない限り、Javaを選択するのが最適です。(ローマでローマ人のように…)

Java(またはC#)での高性能ソフトウェアの作成は、ポイントを証明するためによく行われます…


1
マルチスレッド新しいC ++ 11の標準サポートしています...
ケーシー

@Casey、および実際に使用しているC ++コンパイラの数は?そして、これらのコンパイラの費用はいくらですか。たぶん20年後には役に立つでしょう。それまでは、あなたはそれに頼ることができません。
イアン

かく乱用途はかなりsun.misc.Unsafeたあなたは本当にCの土地にあなたのつま先を浸漬することなく、Javaで低遅延のコードを書くことができないことを示している
ジェームズ・

3
GCCは、C ++のスレッドをサポートしており、それは無料です
ジェームズ・

@Ian:2年後、すべての一般的なコンパイラがサポートしています;)。無料のものでも。
Rutix
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.