問題タブ [string-pool]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java アプリケーションの外部から渡された文字列は、文字列プールに保存されますか?
多くの回答を読みましたが、私の質問に正確に答えているものはありません。
あるポートで Java サービスを実行していて、クライアントがそれに接続して次のようなメソッドを呼び出すとします。
今私の質問は、このキー (clientKey) はサービス側の文字列リテラル プールに格納されますか? 通常、定数プールに格納されるリテラルはコンパイル時に計算されますが、JVM の外部から渡された文字列や、ファイルの読み取り中に渡された文字列はどうなりますか?
java - メソッド ローカル文字列のメモリ割り当て?
String プールと intern() メソッドが Java でどのように機能するかを理解しています。ここで簡単に紹介します。
Java 6 の String.intern()
古き良き時代、インターンされたすべての文字列は PermGen に格納されていました。これは、ロードされたクラスと文字列プールを格納するために主に使用されるヒープの固定サイズの部分です。明示的にインターンされた文字列に加えて、PermGen 文字列プールには、プログラムで以前に使用されたすべてのリテラル文字列も含まれていました (ここで重要な言葉が使用されます。クラスまたはメソッドがロード/呼び出されなかった場合、その中で定義された定数はロードされません)。
Java 6 のこのような文字列プールの最大の問題は、その場所 (PermGen) でした。PermGen は固定サイズで、実行時に拡張できません。-XX:MaxPermSize=96m オプションを使用して設定できます。私の知る限り、デフォルトの PermGen サイズは、プラットフォームによって 32M から 96M の間で異なります。サイズを大きくすることはできますが、サイズは固定されたままです。このような制限により、String.intern を非常に慎重に使用する必要がありました。このメソッドを使用して制御されていないユーザー入力をインターンしない方がよいでしょう。そのため、Java 6 の時点での文字列プーリングは、ほとんどが手動で管理されたマップに実装されていました。
Java 7 の String.intern()
Oracle のエンジニアは、Java 7 の文字列プール ロジックに非常に重要な変更を加えました。文字列プールはヒープに再配置されました。これは、別の固定サイズのメモリ領域によって制限されなくなったことを意味します。すべての文字列は、他のほとんどの通常のオブジェクトと同様にヒープに配置されるようになりました。これにより、アプリケーションのチューニング中にヒープ サイズのみを管理できます。技術的には、これだけでも、Java 7 プログラムで String.intern() を使用することを再検討する十分な理由になる可能性があります。しかし、他にも理由があります。
この時点までは、このツールJava Visualizerに出会うまで、文字列がメモリに格納される方法に慣れていました。プログラムでメモリがどのように割り当てられているかを視覚化するために、次の単純な Java クラスを作成しました。
そして、私は次の結果を得ました:
ご覧のとおり、同じ値を持つ文字列リテラルとオブジェクトが繰り返されてスタックに格納され、メソッド ローカル文字列のヒープ スペースは考慮されません。最初は戸惑いましたが、調べてみると、JDK 7 が自動的に実行するエスケープ解析があることを知りました。しかし、私のコードでは、ヒープに格納する必要がある String オブジェクトを作成しましたが、ビジュアライザーの出力でわかるようにスタック上にありますが、ダミー クラス オブジェクトはヒープに格納されています。私はこの行動を本当に理解できませんでした。メソッドのローカル文字列は、他のオブジェクトやインスタンス レベルの文字列とはどのように異なる方法で扱われますか?
java - StringBuilder.append() メソッドは文字列プールをいっぱいにしますか?
String のほとんどのメソッドを使用すると、文字列プールに追加される新しい文字列オブジェクトが返され、これらのメソッドに引数として渡される文字列リテラルも文字列プールに追加されることがわかっています。
たとえば、次のコードは、"Hello "、""World!""、"Hello World!" という 3 つの文字列オブジェクトを作成します。これらは文字列プールに追加され、concat() メソッドに渡された引数が文字列プールに追加されることを意味します。
StringBuilder.append() メソッドに渡された文字列リテラル引数と StringBuilder の他のメソッドが文字列プールに追加されているかどうかを知りたいです。
または、他のクラスの他のメソッドに渡されるすべての文字列リテラル引数も文字列プールに追加されるかどうかを尋ねる必要がありますか?
また、Java 6に基づいてこれらの事実を知っていることを追加したいと思います.
java - 変数に「2322」ではなく「2122」が含まれるのはなぜですか?
試験問題でした。幸いなことに、私は正しい答えを選びましたが、なぜそれが正しいのかはまだわかりません。
このプログラムを考えてみましょう:
印刷されます2122
。ただし、私は期待し2322
ています (コードを実行すると明らかに間違っています)。その背後にある私の理由:
main メソッドの 3 行目で、D
get の 4 つのインスタンスが初期化されます。のコンストラクタはD
、 の新しいインスタンスを作成しますC
。のインスタンスにC
はString
、メモリ内のスポットを指す変数があります。ここで、 のオブジェクトのインスタンス変数c
、それと呼びましょうはインスタンス変数 (タイプ ) を持ち、 の変数と同じメモリを指している と呼びましょう。c3
d[1]
String
s3
String s1
c1
したがって、 を変更すると、メモリ内の同じ場所を指しているため、s1
の値も変更されることが予想されます。s3
補足として、 のコンストラクターを変更するとD
、以下を参照してください2322
。代わりに取得されます。c3
の変数がd[1]
のメモリ位置を直接指しているので、これは私が期待することですc1
。
これまでの説明に関する私の考え(間違っている可能性があります):
- インスタンス変数
s1
/を初期化するs3
と、新しいオブジェクトが作成されます (これまでのところ、コンストラクターがそのように見えるため、プール内String
を指していると想定していました)"1"
String
C
- を変更する
s1
と、そのポインターはプール内にリダイレクトさ"3"
れString
ます。"1"
プールに入るよりも"3"
。
誰でもこの動作を説明できますか? 私の(誤った)推論の誤りは何ですか?
java - Java の文字列
次の場合の String オブジェクトの動作の正確な理由を知りたいです。
次のスニペットとその仕組みについて知りたいと思っています。
スニペット
質問:
- これらの文字列テキスト、つまりメモリに格納されている文字配列はどこにあるのでしょうか? 「私は String プールに属しています」文字配列は String プール内に存在し、「I'm present on Heap space」文字配列は実際にヒープ領域に存在しますか?
要するに、文字列リテラル参照、文字列リテラルテキスト、文字列オブジェクト参照s2、文字列オブジェクトテキストなどの格納場所を説明してください。
次の投稿のような図式表現は非常に便利です。 http://theopentutorials.com/tutorials/Java/strings/string-literal-pool/
java - 通常のメモリと文字列プールに新しい文字列を作成する
たとえば、次の場合:
それで、
ケース 1 :String str3 = str1.concat(str2)
ヒープまたはプールに入れますか?
ケース 2 :String str4 = str2.concat(“HI”)
ヒープまたはプールに入れますか?
java - 文字列メモリの割り当てと文字列プールの概念
メモリ割り当てと文字列プールに関して、これら 2 つの割り当ての違いは何ですか。
と
java - Java String オブジェクトの作成
私は Java String オブジェクトを読んでいて、この質問がありました-
Javaで2つのオブジェクトを作成しますか?
java - new 演算子を使用して作成された文字列が文字列プールに文字列リテラルを作成する理由
私の質問は、文字列を次のように宣言するときに、文字列プールとヒープで文字列オブジェクトを作成することString a = new String("abc");
の利点は何ですか?
そして、文字列を として作成するときに、ヒープに文字列を作成しないのはなぜですかString a = "abc"
。