
Javaアプリケーションが継ぎ目でクラッシュする状況を経験したことがありますか? 私の場合、これは利用可能なRAMの不足が原因で起こりました。 そして、もちろん、最も都合の悪い瞬間に不足がありました:次の待望のリリースが鼻にあり、コードとデータを更新するためにサーバーの1つが停止し、古いコードの転生はもはや不可能であり、最適化プロセスから気を散らすいくつかの会議とインタビューが計画されています-一般的に、事件は気付かれることはありませんでした。
ちなみに、活力を回復するために適切なバックアップと緊急作業を行っていたら、もっと落ち着いていたはずですが、それはまったく別の話でした。 そのため、通常の操作に15 GBのRAMを欠いているコードと、非常に長くて高価な起動プロセス(約5時間)を自由に使用できます。リモートサーバーのコンソールに表示されます。
停止したサーバーを3日以内に復元するために行う必要のあるすべてのトリックについては説明しませんが、それを私の小さな発見の1つと共有します。
ブールは、高負荷のシステムで使用するデータのタイプではありません。 注意の質問:
たとえば、Ubuntuサーバーx64では、booleanはどのくらいのメモリを使用しますか?
正解は「
不明」で、JVMの実装のみに依存します。普及しているSun JVMを考慮し、仮想マシンの仕様で、
ブール型が存在しないことを確認します。そのため 、intを使用します。 これは、プロセッサアーキテクチャに関係なく、yes / no値を格納するために正確に32ビットが使用されることを意味します。 確かに、同じセクションで、バイト配列に変換されるブール配列を使用するために最適化が行われていることがわかります。これにより、使用可能なメモリが4倍に増加します。 それでも、ゼロまたは1ビットを7ビット余分に格納するための支払いは、サーバーの冒blとjust笑にすぎない場合があります(特に、アレイのサイズが5億要素の場合)。
このような場合の救済はBitSetクラスです。これはブール配列のように動作しますが、データをパックして1ビットのメモリのみが1ビットに割り当てられるようにします(配列全体のオーバーヘッドが低い)。 BitSetは内部にlong型の配列を格納し、特定のビットの値をクエリまたは設定するときに、目的のlongのインデックスを計算し、ビット単位の操作とシフト操作を使用して単一ビットの計算を実行します。
さらに興味深いBitSet実装、
OpenBitSet -Luceneに使用されるApache実装があります。 それははるかに高速ですが、元のBitSetで実行されたいくつかのチェックを見逃します。 使用するものはあなた次第です。