

そもそも、リソースの消費を制御するアプリケーションを作成し、APIを介して上限に達すると、インフラストラクチャにコマンドを与えて制限を増やし、逆もまた同様に、リソースが不要な場合はリソースを取り戻すコマンドを与えました。 このようなアルゴリズムは非常にうまく機能しましたが、テストプロセス中に別のニュアンスが見つかりました:Javaはスケーリングではあまりうまく機能しません。Javaは少量のメモリで開始でき、必要に応じて追加のリソースを使用できますが、OCに戻しません。 これは、JVMエンジニアが特に必要になったときにメモリを取得するプロセスを高速化するために設計されました。 もちろん、これはクラウドモデルでは受け入れられません。
次に、Java、またはガベージコレクターの動作について、シリアル、パラレル、同時マークスイープ、G1などの一連の実験を行いました。
ガベージコレクションの仕組み
Javaでは、オブジェクトの動的割り当てはnew演算子を使用して実現されます。 オブジェクトは、作成されるとすぐにメモリの一部を使用し、オブジェクトへのアクセスがなくなるまでメモリは予約されたままになります。 オブジェクトがアクセスされない場合、それはもはや必要ではないと想定され、それによって占有されたメモリは解放されます。 Javaはオブジェクトをメモリ内で自動的に移動できるため、オブジェクト自体を明示的に破棄する必要はありません。 ガベージコレクションは、この問題を解決する方法にすぎません。 不要なメモリ領域を時間内に解放しないプログラムは、空きメモリの量を制御不能に減少させる可能性があります(いわゆる「メモリリーク」)。 Javaでは、ガベージコレクションはプログラムのライフサイクル全体で自動的に行われるため、メモリを解放する必要がなく、リークを防ぐことができます。 Javaのガベージコレクションの詳細については、 Java Enterprise Performance BookまたはJavarevistedブログを参照してください。
シリアルガベージコレクター(-XX:+ UseSerialGC)
シリアルから始めましょう。 単一のスレッドを使用して、すべてのガベージコレクションを実行します。 シングルプロセッサマシンに最適で、小さなデータセット(最大約100 MB)でアプリケーションを実行するマルチプロセッサに役立つ場合があります。
このガベージコレクターは、スケーリングに関して非常に良い結果を示しました。 コンパクト化のプロパティがあることがわかりました。つまり、メモリの最適化を行い、未使用のリソースをOSに返すと言えます。
JVM 6およびJVM 7でSerial Garbage Collectorをテストして、これをもう一度見てみましょう。
Java 6
より正確には、Javaバージョン1.6.0_27をテストします。
Visual JavaVMユーティリティを起動します。これにより、コンピューターで実行されているすべてのJavaプロセスを監視したり、これらのプロセスがメモリを消費する量を監視したりできます。
テストには、無限ループでメモリを動的に割り当てたり解放したりするプログラムを使用します。
パブリック クラス Memoryleak {
public static void main ( String [ ] args ) {
システム アウト 。 println ( "START ...." ) ;
while ( true ) {
システム アウト 。 println ( "next loop ..." ) ;
{
int count = 1000 * 1024 ;
バイト [ ]配列= 新しい バイト [ 1024 *カウント] ;
スレッド 睡眠 ( 5000 ) ;
配列= null ;
システム gc ( ) ;
システム gc ( ) ;
スレッド 睡眠 ( 5000 ) ;
} catch ( InterruptedException ex ) {
}
}
}
}
次のパラメーターを使用してJVMを実行します。
-XX:+ UseSerialGC -Xmx1024m -Xmn64m -Xms128m -Xminf0.1 -Xmaxf0.3 、ここで
-XX:+ UseSerialGC-ガベージコレクターシリアルを使用します。
-Xmx1024m -RAMの最大使用-1024 MB;
-Xmn64m -64 Mbに等しいヒープステップ。
-Xms128m -128 MBに等しいヒープの最小値。
-Xminf0.1-このパラメーターは、ヒープ内の最小空きスペースを定義し、ガベージコレクション後に少なくとも10%の空きスペースがない場合にJVMに拡張するよう指示します。
-Xmaxf0.3-このパラメーターは、ヒープの拡張量を決定し、空き容量が30%を超える場合にJVMに圧縮するよう指示します。
デフォルトでは、 XminfとXmaxfの値はそれぞれ0.3と0.6ですが、実験では、垂直スケーリングの振幅を大きくするためにこれらの制限を大幅に削減しました。
その結果、プログラムを実行する別のプロセスに従って、メモリが動的にいっぱいになり、解放されることがわかります。

また、リークがないことを確認するために、消費された合計メモリのグラフを見てみましょう。

Java 7
jdkバージョン1.7.0_03をテストします
同じプログラムを使用し、JVMに同じパラメーターを設定します。 JDK 7でわかるように、すべてがスムーズです。

良い結果ですが、残念ながら、前述したように、このガベージコレクターはシングルプロセッサマシンと少量のメモリでのみ動作します。これは、大きくてかさばるアプリケーションが機能するには不十分です。
パラレルガベージコレクター(-XX:+ UseParallelGC)
Parallelは小さなガベージコレクションの作業を並行して行うことができ、リソースと時間の消費を大幅に削減できます。 これは、マルチプロセッサおよびマルチスレッドマシンで実行される中規模および大規模のデータセットアプリケーションに役立ちます。
Parallel Garbage Collectorの実験を繰り返しましょう。
Java 6の合計メモリ使用量の結果:

Java 7の場合 :

パラレルは、もちろん、シリアルよりも多くの利点があります。たとえば、マルチスレッドアプリケーション、マルチプロセッサマシンで動作し、大量のメモリをすばやく処理できます。 しかし、残念ながら、グラフで見るように、未使用のリソースはオペレーティングシステムに返されません。
同時マークスイープガベージコレクター(-XX:+ UseConcMarkSweepGC)
同時マークスイープは、アプリケーションの実行中にほとんどの作業を実行します。 これにより、ガベージコレクションの一時停止を大幅に削減できます。 全体的なスループットよりも応答時間が重要な中規模および大規模のデータセットを使用するアプリケーション向けに設計されています。
コンカレントマークスイープに対して手順を再度繰り返します。
繰り返しますが、状況は前の状況と似ています。
Java 6 :

Java 7 :

G1ガベージコレクター(-XX:+ UseG1GC)
次に、G1が表示されます。G1は、並列および同時マークスイープのすべての利点を備えており、すべての要件を満たしています。
テストを開始しましたが、G1を長時間動作させると、安定したメモリリーク定数が観察されることがわかりました。
Java 6 :

もちろん、この問題はOracleの担当者に対処しました。 サンクトペテルブルクのオラクルの従業員であるIvan KrylovとVladimir Ivanovは私たちのリクエストに迅速に対応しました。その結果、この問題はJVM 7で修正されました。

ご覧のとおり、Java 7ではすべて問題ありませんが、高度なG1はその使命を完全に果たしました。
ご存知のように、リソースの使用に対して支払う能力は、各クライアントと企業にとって非常に重要な要素です。 誰も過払いすべきではありません。 ただし、この方向での急速な発展を妨げるブロッカーがいくつかあります。 ホスティング業界の革命を継続するために最善を尽くします。
以下のビデオは、Jelasticで自動ズームがどのように機能するかを説明しています:
*不明な理由により、G1のメモリリークに関するレポートの公式バグがOracleデータベースから削除されました。 このバグの詳細については、 こちらをご覧ください 。