ホームページ Java &#&チュートリアル Java での文字列のメモリ割り当て

Java での文字列のメモリ割り当て

Sep 11, 2024 am 06:33 AM

Memory Allocation of Strings in Java

Java では、文字列は String クラスのオブジェクトとしてメモリに保存されます。

Java プログラムにメモリが割り当てられると、JVM (Java 仮想マシン) は割り当てられたメモリを 2 つの部分に分割します。 1 つの部分はスタック、もう 1 つの部分はヒープです。ヒープ メモリでは、Java は一部のメモリを割り当てます。特にリテラルに対して、そのメモリは文字列定数プール (SCP) と呼ばれます。 SCP は、ヒープ内の事前定義された領域です。文字列プールは、Java ランタイム用のスペースを大幅に節約するのに役立ちます。 String クラスは SCP を使用して一意の文字列リテラルを保存します。

スタック メモリには、変数、変数参照、またはオブジェクトへの参照が保存されます。

ヒープメモリには、動的に割り当てられたすべてのオブジェクトが格納されます。オブジェクトにメモリを割り当てるには、新しいキーワードを使用します。

文字列オブジェクトを作成するには 2 つの方法があります。

  1. 文字列リテラル

文字列 str1 = “MyString”;

文字列リテラルを作成するときは常に、JVM はまず文字列リテラルが文字列定数プールにすでに存在するかどうかを確認します。利用できない場合は、SCP に新しい文字列リテラルが作成されます。

上の図では、str1 は SCP の「MyString」を指しています。新しく作成された文字列リテラルの処理方法は次のとおりです。

  1. 新しいキーワードを使用する

String str2 = new String(“MyString”); //新しいキーワードを使用して文字列クラスをインスタンス化します

新しいキーワードを使用して文字列オブジェクトを作成すると、2 つのオブジェクトが作成されます。 1 つは SCP に、もう 1 つはヒープにあり、参照変数はスタックに保存されます。

を使用してリテラルの「MyString」をすでに作成しています。

文字列 str1 = “MyString”;

SCP 内に重複を持たせることはできないため、JVM は SCP 内にもう 1 つのオブジェクトを作成しませんが、スタック内の変数 str3 への既存の参照を返し、ヒープ内に 1 つのオブジェクトを作成します。 Str3 はヒープ内のオブジェクト「MyString」を指しますが、SCP 内にはありません。

以下は、文字列オブジェクトにメモリが割り当てられる方法のさまざまなケースです。

ケース 1: 上記で定義された文字列オブジェクトがメモリに格納される方法。

パブリック クラス stringsStorageConcept

{

public static void main(String[] args)

{

文字列 str1 = “MyString”;

String str2 = new String(“MyString”);

System.out.println(str1 == str2); //出力:False

System.out.println(str1.equals(str2)); //出力:True

}

}

「==」演算子を使用して str1 と str2 を比較すると、false が返されます。ご存知のとおり、「==」演算子は物理アドレスを比較します。この例では、str1 は SCP 内のオブジェクトを指し、str2 はヒープ内のオブジェクトを指します。したがって、 false を返します。
しかし、str1.equals(str2) の場合、ご存知のとおり、「equals」関数は個々の文字をチェックし、str1 と str3 の両方に同じ値が格納されているため、true が返されます。

ケース 2: 別の文字列リテラル

文字列 str3 = “MyString”;

str1 と str3 は両方とも、SCP 内の同じ文字列リテラルを指します。

パブリック クラス stringsStorageConcept

{

public static void main(String[] args)

{

文字列 str1 = “MyString”;

文字列 str3 = “MyString”;

System.out.println(str1 == str2); //出力:True

System.out.println(str1.equals(str2)); //出力:True

}

}

s1 == s3 は、「==」演算子が物理アドレスを比較するが内容は比較しないため、true を返します。
s1.equals(s3) は true を返し、「equals」関数は両方の参照変数の個々の文字をチェックします。

ケース 3: 新しいキーワードを使用して別の文字列オブジェクトが作成されます

String str4 = new String(“NewString”);

この場合、JVM は SCP でこの文字列をチェックします。値「NewString」を持つ文字列オブジェクトが見つからないため、SCP とヒープに 2 つのオブジェクトを作成し、参照変数 str4 は次の場所に保存されます。スタック。 Str4 にはヒープ内のオブジェクトへの参照が含まれます。

ケース 4: 別の文字列リテラルが作成されます。

文字列 str5 = “NewString”;

この場合、JVM はこのリテラルがすでに利用可能かどうかを SCP でチェックします。ここでは「NewString」が SCP にすでに存在しているため、JVM は SCP に重複を作成せず、代わりに変数 str5 への参照を返します。

ケース 5: ある文字列を別の文字列に代入する

String str4 = new String(“NewString”);

文字列 str6 = str4; //代入

ここで、str6 と str4 はヒープ内の同じオブジェクトを指し、str4 の値は消去されません。

パブリック クラス stringsStorageConcept

{

public static void main(String[] args)

{

String str4 = new String(“NewString”);

文字列 str6 = str4;

System.out.println(str4 == str6); //出力: true

}

}

JVM は、ヒープ内の「NewString」の参照を変数 str6 に与えます。これが、str4 == str6 が true を返す理由です。

結論として、文字列リテラルを使用し、「new」演算子によって文字列オブジェクトを作成することには、長所と短所があります。

文字列リテラルを使用すると、重複を作成せずにメモリをより効率的にすることができます。 JVM は 1 つの一意のオブジェクトを作成し、文字列は SCP 内に永久に残ります。この欠点は、文字列プールのサイズが固定されており、いつかいっぱいになることです。
しかし、新しいキーワードを使用すると、2 つのオブジェクトが作成され、1 つは SCP に、もう 1 つはヒープに作成されます。ヒープでは、オブジェクトが必要ない場合、スペースを作るためにガベージ コレクターによって消去されます。しかし、この欠点は、「new」演算子を使用すると、JVM が常に新しいオブジェクトを作成する必要があり、JVM にとって過負荷になることです。

以上がJava での文字列のメモリ割り当ての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? 会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? Apr 19, 2025 pm 04:51 PM

一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? 名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? Apr 19, 2025 pm 11:30 PM

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? Apr 19, 2025 pm 06:21 PM

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? Apr 19, 2025 pm 11:42 PM

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Apr 19, 2025 pm 11:45 PM

intellijideaultimatiateバージョンを使用してスプリングを開始します...

Javaオブジェクトを配列に安全に変換する方法は? Javaオブジェクトを配列に安全に変換する方法は? Apr 19, 2025 pm 11:33 PM

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? Apr 19, 2025 pm 11:27 PM

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。

Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Apr 19, 2025 pm 11:36 PM

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。

See all articles