ホームページ  >  記事  >  Java  >  String、StringBuffer、StringBuilder の違いと Java でのスタック メモリ割り当ての図による紹介

String、StringBuffer、StringBuilder の違いと Java でのスタック メモリ割り当ての図による紹介

黄舟
黄舟オリジナル
2017-03-04 09:33:061983ブラウズ

Java の String クラスは非常に一般的に使用されるクラスですが、その詳細にはほとんど注意が払われていないため、ほとんどのインタビューはこのクラスに焦点を当てます。たとえば、 String str = new String("hello"); は、いくつかのメモリ空間、String と StringBuffer の違いなどを開きます。私の理解は次のとおりです:

String は Final によって変更されたクラスであり、継承することはできません。 StringBuffer も、final によって変更されたクラスです。

1. JVM のメモリ分割

Java には主に 4 つのメモリ空間があります: スタック メモリ空間、ヒープ メモリ空間、グローバル データ領域、グローバル コード領域

1. スタック メモリ空間: すべてのオブジェクトを保存します。 name (参照されたヒープメモリ空間のアドレスを保持)

2. ヒープメモリ空間: 各オブジェクトの特定の内容を保存します

3. グローバルデータ領域: 静的型のデータ属性(グローバルデータ)を保存します

4. グローバルコード領域: すべてのメソッド定義を保存します


JVM では、ヒープメモリはオブジェクトのインスタンス化の内容 (プログラムデータ) を格納するメモリ空間であり、スタックメモリはオブジェクトの名前を格納します。対応するヒープを指すアドレス。

また、次のようにも言えます。すべてのオブジェクト名はスタック メモリに格納され、オブジェクトの特定の内容はヒープ メモリに保持されます。参照型データは、ヒープ メモリの領域を空けるために new キーワードを使用する必要があります。

2. Sring のメモリ割り当て

String には特別な機能があります。String オブジェクトを構築するときに、new 構築または "hello" 直接構築を使用できます。 2 つの方法のうち、2 番目の方法を使用することをお勧めします。

1. String a = "hello";

2. String a= new String("hello");

説明は次のとおりです:

1: a のオブジェクト参照がスタックに定義されていますヒープを指すメモリ。メモリの値は「hello」メモリ アドレスです。ついに記憶空間がオープンしました

2: a のオブジェクト参照がスタック メモリ内で再定義され、最初にヒープ メモリ内の "hello" のメモリ アドレスを指し、次に新しい後にヒープ メモリ内の "hello" のアドレスを指します。最終的に、2 つのスペースが開かれました。最初のスペースにはオブジェクト参照がなく、JVM によってガベージ コレクションが行われます。

図は次のとおりです:

次のコードを理解するのは難しくありません:

 
package andy.string.test;  
  
/**   
 * @author Zhang,Tianyou   
 * version:2014-11-25 下午4:15:14   
 *  
 *   
 */  
  
public class TestString {  
  
    public static void main(String[] args){  
        String a = "hello";  
        String b = "hello";  
        String c = new String("hello");  
        String d = new String();  
        d = "hello";  
        String e = c;  
          
        System.out.println("a==b ? " + (a== b));  
        System.out.println("a==c ? " + (c== b));  
        System.out.println("a==d ? " + (a== d));  
        System.out.println("a==e ? " + (a== e));  
        System.out.println("c==d ? " + (c== d));  
        System.out.println("c==e ? " + (c== e));  
    }  
}



a==b==d だけがあります。 c=e。


説明:

1. string は、new されるたびにヒープメモリを待ちたくないので、new が新しいアドレスを割り当てた後、d は new の後のアドレスを放棄し、メモリアドレスを指します。 a に対応するため、それらは同一です。

2. "hello" 代入の直接代入方法が指すヒープメモリ空間は同じです。 String は Java の共有デザインを使用します。このオブジェクト プールは、複数のオブジェクトを保存できます。新しくインスタンス化されたオブジェクトがオブジェクト プールにすでに存在する場合、そのオブジェクトは繰り返し定義されず、オブジェクト プールから直接使用されます。 。したがって、既存のコンテンツの場合、オブジェクトはすでにインスタンス化されているオブジェクトのスペース アドレスを指します。

3. e は C のメモリ空間を直接指します。

4. したがって、文字列を使用する場合は、メモリ容量を削減し、パフォーマンスを向上させるために、直接割り当てを使用することをお勧めします。

3. String、StringBuffer、StringBuilderの違い

1. String、StringBuffer、StringBuilderはすべてfinalによって変更され、継承したり書き換えたりすることはできません。

2. String がインスタンス化された後、そのメモリ空間の内容サイズは変更できません。StringBuffer はスレッドセーフな変数文字シーケンスであり、ヒープ メモリ内の内容はインスタンス化後に動的に変更できるため、メモリ長とサイズは変更できません。 StringBuilder がインスタンス化された後は、メモリのサイズと長さも可変です、いいえ

違いは、StringBuilder はスレッド同期されていないため、その操作は StringBuffer よりも効率的である必要があることです。

実際、上記のコードはメモリ内に 3 つのスペース、つまり「hello」、「andy」、「helloandy」を解放し、それらのヒープ メモリ サイズは固定されており、最後に str は「helloandy」のヒープ アドレスを指します。 。以下の図に示すように、 StringBuffer を使用すると、メモリ空間は 1 つだけ開かれ、APEND を使用して削除などの操作内容を追加できます。

文字列 オブジェクトが生成されるたびに、システムのパフォーマンスに影響します。特に、メモリ内に参照されていないオブジェクトが多すぎると、JVM の GC が動作し始め、速度が確実に遅くなります。ただし、StringBuffer/StringBuilder クラスを使用する場合、結果は毎回異なります。新しいオブジェクトを生成してオブジェクト参照を変更するのではなく、StringBuffer/StringBuilder オブジェクト自体に対する操作になります。

したがって、文字列に値を循環的に代入する場合は、メモリを節約してパフォーマンスを向上させることができる StringBuffer (スレッドセーフ) または StringBuilder を使用するのが最善です。 上記は、Java の String、StringBuffer、StringBuilder の違いとスタック メモリの割り当てを図で紹介したものです。さらに関連する内容については、PHP の中国語 Web サイト (www.php.cn) に注目してください。

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