短いバージョン: string.substring(n,m).intern() を呼び出す場合、文字列テーブルは部分文字列または元の文字列を保持しますか?
...しかし、それが正しい質問であるかどうかはわかりません。そのため、長いバージョンを次に示します。
私は、ファイルを 1 つの大きな文字列として丸呑みし、String.split、.trim、.substring、および StringTokenizer を使用してそれらをトークンに分解することにより、ファイルを解析する従来の Java コード (PCGen) を使用しています。これらのメソッドはいずれも元の文字列をコピーせず、すべてが共有 char[] の一部を指しているため、これは解析に非常に効率的です。
解析が終わったら、メモリを解放したいと思います。元の大きな文字列のいくつかの小さな部分文字列だけが必要ですが、強力な参照によって大きな文字列が収集されなくなります。その後、私は OOM に苦しんでいます。これは、多くの解析済みファイルのヒープへの大きな影響が原因の 1 つだと思います。
new String(String)
(コピーオンライト)を介して大きな文字列を削除できることはわかっています。そして、 String.intern を介して文字列の重複を減らすことができることを知っています (解析されたファイルには多くの冗長性があるため、これは重要です)。最大量のヒープを再利用するには両方を使用する必要がありますか?それとも .intern() で両方を行う必要がありますか? OpenJDK7 ホットスポット ソース コード (hotspot/src/share/vm/classfile/symbolTable.cpp) を読むと、文字列テーブルが文字列全体を保持し、オフセット/長さをまったくトリミングしていないように見えます。そのため、新しい文字列を作成し、その結果をインターンする必要があると思います。右?
そうは言っても、ストリーミング パーサーに切り替えることは、メモリの観点からは大きなメリットですが、短期的には大きすぎる変化です。