JVM メモリ割り当てと一般的な文字列メソッド

JVM メモリ割り当てと一般的な文字列メソッド

[[275905]]

1. JVM メモリ割り当てと定数プール

String クラスを紹介する前に、JVM でメモリがどのように割り当てられるかを簡単に分析してみましょう。次の図に示すように (注: jdk1.8 以降ではメソッド領域はありません)。

前述のように、JVM はメモリを複数の異なる領域に分割します。これらのエリアには、独自の用途、作成および破壊の時期があります。一部の領域は仮想マシン プロセスの開始時に存在しますが、一部の領域はユーザー スレッドの開始と終了に応じて作成および破棄されます。

地域名の説明:

1.1、方法領域:

​ これはデータ共有メモリ領域に属し、クラス情報、定数、静的変数、ジャストインタイムコンパイラによってコンパイルされたコード、および仮想マシンによってロードされたその他のデータが格納されます。

1.2、仮想マシンスタック

仮想マシン スタックは、通常スタックと呼ばれています。 Java 実行メソッドのメモリ モデルです。メソッドが実行されるたびに、スタック フレームが作成されます。スタック フレームはスタックにプッシュされ、Java メソッド呼び出しが通常の結果を返すか例外をキャッチすると、スタック フレームはスタックからポップされます。

スタック フレーム: スタック フレームには、ローカル変数テーブル、戻り値、オペランド スタック、動的リンクなど、メソッドに関連する情報が格納されます。

1.3、ローカルメソッドスタック

​ 機能的には仮想マシン スタックに似ていますが、仮想マシン スタックはバイトコードを実行するのに対し、ローカル メソッド スタックはネイティブ メソッドを呼び出し、スレッド専用です。

1.4、プログラムカウンタ

プログラム カウンターはスレッド固有であり、現在のスレッドによって実行されたバイトコードの行番号を記録します。複数のスレッドが実行されると、CPU はスレッド間を切り替えます。では、再びスレッドに戻ったとき、スレッドのストレージ ユニットと実行命令をどのようにして知るのでしょうか。プログラム カウンターは次のストレージ ユニットのアドレスを格納します。実行が完了すると、プログラム カウンターは自動的に 1 増加し、このサイクルはプログラムが終了するまで継続されます。

1.5、ヒープ

ヒープの概念といえば、誰もがよく知っているはずです。記憶において重要な役割を果たします。これは主に、キーワード new によって作成されたオブジェクトを格納するために使用され、すべてのスレッドで共有される最大の領域です。

==特記事項: JDK1.7 以降では、定数プールはヒープ メモリに移動されます。 ==

ヒープには、コンパイル中に生成されたリテラルとシンボル参照を格納するために使用される定数プールも含まれます。この部分のコンテンツは、クラスがロードされた後にメソッド領域に保存されます。同時に、String クラスの intern() メソッドによって生成される定数など、実行時に生成される新しい定数も定数プールに格納できます。

​ 定数プールは、この型で使用される定数の順序付けられたコレクションです。直接定数 (プリミティブ型、文字列) と他の型、メソッド、フィールドへのシンボリック参照が含まれます。

2. 定数プール

2.1、定数とは何か?

定数は final によって変更される変数です。一度値が決定されると、変更することはできません。

​ final は静的変数、メソッド、インスタンス変数、ローカル変数を変更できます。

​ 定数プールは、静的定数プールとランタイム定数プールの2つの形式に分かれています。

2.2、静的定数プール

つまり、*.class ファイル内の定数プールです。クラス ファイル内の定数プールには、文字列 (数値) リテラルだけでなく、クラスとメソッドの情報も含まれており、クラス ファイルのスペースの大部分を占めています。この定数プールは、リテラルとシンボリック参照を格納するために使用されます。

2.3、ランタイム定数プール

​ これは、JVM 仮想マシンがクラスのロード操作を完了した後、クラス ファイル内の定数プールをメモリにロードし、メソッド領域に保存することを意味します。よく参照される定数プールは、メソッド領域内のランタイム定数プールです。同様に、ランタイム定数プールの重要な特徴はその動的な性質です。つまり、定数はコンパイル時にのみ生成する必要はありません。 String クラスの intern() メソッドなど、新しい定数も実行時に定数プールに保存されます。

3. == とイコール

3.1、両者の境界

==:

基本型の場合: == は数値比較を示します

参照型の場合: == はアドレス値の比較を意味します

等しい:

比較されるのは、2つの間の値が等しいかどうかですが、Javaのすべてのクラスは直接的または間接的にObjectクラスを継承しており、equalsも例外ではありません。実際、== は、次に示すように、equals ソース コードでの比較にも使用されます。

  1. ![](https://img2018.cnblogs.com/blog/1655301/201909/1655301-20190902223856542-1095893842.png)

それで質問は、これと == の違いは何ですか?

前述のように、equals も java.lang.Object から継承されるため、equals を書き換えて独自の比較メソッドを定義することができます。

次のコードを参照してください。

  1. 文字列 str1 = "abc" ;
  2. 文字列 str2 = "abc" ;
  3.  
  4. char [] strArray = { 'a' , 'b' , 'c' };
  5. 文字列 str3 = 新しい文字列(strArray);
  6.  
  7. 文字列 str4 = "abc" ;
  8.  
  9. システム。出力.println(str1 == str2);
  10. システム。出力.println(str1 == str3);
  11. システム。出力.println(str2 == str3);
  12. システム。出力.println(str4.equals(str1));

上記の操作結果は次のとおりです。

  1. 真実 
  2. 間違い 
  3. 間違い 
  4. 真実 

次に、上記の結果を一つずつ分析します。

1. str1 と str2 は文字列オブジェクトのアドレスを比較します。値は同じなので、アドレス値も同じです。

2. str3 は新しいサンプルオブジェクトです。ヒープメモリ内に新しいメモリアドレスが開かれます。それは一定のプール内にはありません。したがって、返される結果は false になります。

3. 同様に、str2 と str3 を比較すると、同じ結果になります。

​ 4. equals は値が同じかどうかを比較するので、返される結果は true になります。

図に示すように:

4. 一般的な文字列メソッド

まず、文字列を宣言します。

  1. 文字列 str1 = "abc" ;

4.1、int 長さ()

  1. さ = str1.length();
  2. System.out.println(長さ) ;

4.2、char charAt(値)

  1. 文字列 str = "abc" ;
  2. char c = str.charAt(1);
  3. システム.out.println (c) ;

4.3、char toCharArray()

  1. 文字列 str = "abc" ;
  2. char c[] = str.toCharArray();
  3. ( int i = 0; i < c.length; i++) {
  4. システム。 out .println( "配列出力に変換: " + c[i]);
  5. }

4.4、int indexOf("文字"); int lastIndexOf("文字")

  1. 文字列 str = "axcdefgabc" ;
  2. int a1 = str.indexOf( "a" );
  3. int a2 = str.indexOf( "x" , 2);
  4. int a3 = str.lastIndexOf( "c" );
  5. System.out.println ( "あなたの場所:" + a1);
  6. システム。 out .println( "場所は:" + a2);
  7. システム。 out .println( "ドットの最後の位置は:" + a3);

4.5、文字列の大文字と小文字の変換

​ 大文字に変換します();大文字に変換

​ 小文字に変換();小文字に変換

  1. 文字列 str = "hello world" ;
  2. 文字列 str1 = "HELLO WORD" ;
  3. システム。 out .println( "文字列を大文字に変換します: " + str.toUpperCase());
  4. システム。 out .println( "文字列を小文字に変換します: " + str1.toLowerCase());

4.6、String[] 分割("文字")

  1. 文字列 str = "abc,def,123" ;
  2. 文字列[] arr1 = str.split( "," );

4.7、ブール値は(Object anObject)に等しい

  1. 文字列 str = "abc" ;
  2. 文字列 str1 = "123" ;
  3. if(str.equals(str1)) {
  4. System.out.println ( "等しい" ) ;
  5. }
  6. それ以外{
  7. System.out.println ( "等しくない" );
  8. }

4.8、文字列トリム()

  1. 文字列 str = " abc " ;
  2. システム。 out .println( "左右のスペースを削除した後: " + str.trim());

4.9、文字列の置換

  1. 文字列の置換( char oldChar, char newChar)
  2. String replaceAll(String,String)はすべてのコンテンツを指定されたコンテンツに置き換えます
  3. 文字列repalceFirst(String,String)は、特定のコンテンツの最初の出現を指定されたコンテンツに置き換えます。
  4.  
  5. 文字列 str = "abcdefgabdc" ;
  6. System.out.println ( "置換:" + str.replace ( "abc" , "123" ) );
  7. システム。 out .println( "すべて置換: " + str.replaceAll( "ab" , "12" ));
  8. システム。 out .println( "最初の出現箇所を置き換えます: " + str.repalceFirst( "a" , "a" ));

4.10、文字列の部分文字列(int beginIndex、int endIndex)

  1. 文字列 str = "abcdefg" ;
  2. // 位置 3 を除く位置 0-3 の内容をインターセプトします
  3. システム。 out .println( "インターセプトされた文字は次のとおりです: " + str. substring (0, 3));
  4. // 2を含む3番目の位置からインターセプトを開始します
  5. システム。 out .println( "インターセプト後の文字は次のとおりです: " + str. substring (2));

4.11、ブール型equalsIgnoreCase(文字列)

  1. 文字列 str = "ABC" ;
  2. 文字列 str1 = "abc" ;
  3. if(str.equalsIgnoreCase(str1)){
  4. System.out.println ( "等しい" ) ;
  5. }
  6. それ以外{
  7. System.out.println ( "等しくない" );
  8. }

4.12、ブール値を含む(文字列)

  1. 文字列 str = "ABCDEF" ;
  2. 文字列 str1 = "ABC" ;
  3. if( str.contains (str1)){
  4. システム。 out .println( "str コンテンツに ABC が含まれています" );
  5. }
  6. それ以外{
  7. システム。 out .println( "str に ABC が含まれていません" );
  8. }

V. 結論

​ 1. JVM メモリの割り当てについて、jdk6 ではメソッド領域がありましたが、jdk8 ではメソッド領域がなくなり、メタ領域に変更されました。

​ 2. jdk6では定数プールはメソッド領域に存在し、jdk7以降では定数プールはヒープへ移動されます。

<<:  「テクノロジー+製品+サービス」という新しい製造モデルが業界のバリューチェーンを再構築

>>:  クラウド コンピューティング 2.0: ハイブリッド クラウドの新時代

推薦する

企業ネットワークマーケティングの実務経験

何をするにしても、紙の上で話すだけでは無駄です。真実は実践から生まれます。諺にあるように、実践は真実...

ウェブマスターの今後の方向性はFacebookのリストからわかる

最近私が最も注目しているのは、FacebookのIPO問題です。私がFacebookを初めて知り、注...

コンテナ ソフトウェア市場で勝利するのは誰か?

[[410982]] Red Hat は、コンテナ顧客に必要なトレーニングのせいで、コンテナ ソフト...

lunarpages-無制限の仮想ホスティング/1年間購入すると1年間無料/1つの無料ドメイン名

lunarpages のメールプロモーションで、大きな国イベントが開催されています。具体的に何なのか...

Hosteons VPSはどうですか? Dallas AMD Ryzen+NVMe シリーズのレビュー

ホストオンはどうですか?ホストは良いですか? Hosteons の AMD Ryzen+NVMe に...

ECサイトにおける購買意欲と購買ターゲットの分析

消費者として、次のような経験をしたことはありませんか。Dangdang.com で 3 年間本を購入...

Redisson 分散ロック ソースコード フェアロック ロック

[[408379]]序文デフォルトのロックロジックは不公平です。ロックが失敗すると、スレッドは wh...

全能ではない:WeChat O2Oはまだ単なる話

戦争について書面で語ることは軍事戦略においては大きなタブーである。ビジネスは戦場のようなものです。自...

ソフト記事シリーズを継続的に更新してうまくやっていく方法

コンテンツ編集は、詩、散文、議論文など、さまざまな形式、または任意の形式を取ることができます。ソフト...

エンタープライズ クラウド ソリューション: 最適なモデルはどれですか?

今日のデジタル時代では、あらゆる規模の企業が、ビジネスの効率、柔軟性、リモート アクセス、スケーラビ...

高品質なソフト製品に求められる条件

ウェブサイトを運営したりブログを書いたりしている友人の多くが、よく次のような質問をします。「良いソフ...

次世代インターネットの開発を加速させるため、アリババはIPv6の大規模な適用を発表した。

IPv4 アドレスは枯渇に近づいています。次世代のインターネット技術として歓迎されている IPv6 ...

Baidu Advanced Phrase 2.0 マッチングモードで注意すべき問題

新しいプランを追加したのですが、ブロードにすると表示されません。精密をオンにしたようなもので、キーワ...

Smarthost: イースター VPS プロモーション 30% オフ、月額 2 ドルから、28 のデータ センターから選択可能

Smarthost がイースター プロモーションを開始しました。ブロック ストレージ VPS を除く...

ネットワークマーケティングにおける最も重要な動き

序文: 昨晩統計をとったとき、実は秘密にしていました。「インターネット マーケティングで最も重要な動...