1. 序章

変数を宣言したりオブジェクトを作成したりするときはいつでも、それはメモリに保存されます。 大まかに言えば、Javaはメモリをスタックとヒープの2つのブロックに分割します。 両方のメモリは特定のタイプのデータを保存し、保存とアクセスのパターンが異なります。

このチュートリアルでは、さまざまなパラメーターを調べて、String定数プールを格納するのに最も適切な領域を学習します。

2. 文字列定数プール

String constantpoolは特別なメモリ領域です。 文字列リテラルを宣言すると、JVMはオブジェクトをプールに作成し、その参照をスタックに格納します。文字列オブジェクトをメモリに作成する前に、JVMはいくつかの手順を実行して減少させますメモリオーバーヘッド。

文字列定数プールは、その実装でハッシュマップを使用します。 ハッシュマップの各バケットには、同じハッシュコードを持つ文字列のリストが含まれています。 以前のバージョンのJavaでは、プールのストレージ領域は固定サイズであり、多くの場合、「オブジェクトヒープ用に十分なスペースを予約できませんでした」エラーが発生する可能性がありました。

システムがクラスをロードすると、すべてのクラスの文字列リテラルがアプリケーションレベルのプールに移動します。異なるクラスの等しい文字列リテラルが同じである必要があるためです。 オブジェクト。 このような状況では、プール内のデータは、依存関係なしに各クラスで利用できる必要があります。

通常、スタックには短命のデータが格納されます。 これには、ローカルプリミティブ変数、ヒープオブジェクトの参照、および実行中のメソッドが含まれます。 ヒープは動的メモリ割り当てを可能にし、実行時にJavaオブジェクトとJREクラスを格納します。

ヒープはグローバルアクセスを許可し、ヒープ内のデータストアはアプリケーションの存続期間中すべてのスレッドで利用できますが、スタック上のデータストアはプライベートスコープを持ち、所有者スレッドのみがそれらにアクセスできます。

スタックはデータを連続したメモリブロックに格納し、ランダムアクセスを許可します。 クラスがプールからランダムなStringを必要とする場合、スタックのLIFO(後入れ先出し)ルールのために使用できない可能性があります。 対照的に、ヒープはメモリを動的に割り当て、任意の方法でデータにアクセスできるようにします。

さまざまなタイプの変数で構成されるコードスニペットがあると仮定します。 スタックは、 intliteralの値とStringおよびDemoオブジェクトの参照を格納します。任意のオブジェクトの値はヒープに格納されます。 String リテラルは、ヒープ内のプールに入ります。

スタック上に作成された変数は、スレッドが実行を完了するとすぐに割り当てが解除されます。 対照的に、ガベージコレクターはヒープ内のリソースを再利用します。 同様に、ガベージコレクターは、参照されていないアイテムをプールから収集します。

プールのデフォルトサイズはプラットフォームによって異なる場合があります。いずれの場合も、使用可能なスタックサイズよりもはるかに大きくなります。 JDK 7より前は、プールはpermgenスペースの一部でしたが、JDK 7から現在までは、メインヒープメモリの一部です。

3. 結論

この短い記事では、String定数プールのストレージ領域について学習しました。 スタックとヒープには、データの保存とアクセスの特性が異なります。 メモリ割り当てからそのアクセスと可用性まで、ヒープは文字列定数プールを格納するのに最も適した領域です。

実際、プールはスタックメモリの一部ではありませんでした。