以下の説明では、データのプレーンメモリのみが対象です。構造体に対する追加のメモリの必要性はすべて除外されます。これは詳細なディテールとしての概要です。
メモリはラインparcour += line
が
new StringBuilder().append(parcour).append(line).toString()
としてクラスファイルにコンパイルされ、これらのライン
String parcour = "";
...
String line = bReader.readLine();
...
parcour += line;
で食べられるがparcour
は10メガバイトとline
のサイズであろう大きさの文字列が含まれていると2 MB。次いでparcour += line;
中に割り当てられたメモリは、新たに作成された文字列をparcour
34の周りMBに割り当てられる前に(略)
// creates a StringBuilder object of size 12 MB
new StringBuilder().append(parcour).append(line)
// the `.toString()` would generate a String object of size 12 MB
new StringBuilder().append(parcour).append(line).toString()
コードが必要であろう。
parcour = 10 MB
the temporary StringBuilder object = 12 MB
the String fromStringBuilder = 12 MB
------------------------------------------
total 34 MB
OutOfMemoryException
がもっと早くあなたが現在予想し、その後スローされていることを示すための小さなデモスニペット。
OOMString.java
class OOMString {
public static void main(String[] args) throws Exception {
String parcour = "";
char[] chars = new char[1_000];
String line = new String(chars);
while(line != null)
{
System.out.println("length = " + parcour.length());
parcour += line;
}
}
}
OOMStringBuilder.java
class OOMStringBuilder {
public static void main(String[] args) throws Exception {
StringBuilder parcour = new StringBuilder();
char[] chars = new char[1_000];
String line = new String(chars);
while(line != null)
{
System.out.println("length = " + parcour.length());
parcour.append(line);
}
}
}
どちらのスニペットは、同じことを行います。彼らはOutOfMemoryException
がスローされるまで、parcour
に1000文字の文字列を追加します。それを高速化するために、ヒープサイズを10 MBに制限しています。 java -Xmx10m OOMStringBuilder
length = 2052000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
のjava -Xmx10m OOMString
length = 1048000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
出力の
出力あなたはOOMString
はOOMStringBuilder
よりも(さらに短い長さで)失敗するより多くの時間を必要としていることに気づくだろうコードを実行すると。
また、1文字が2バイト長であることに注意する必要があります。あなたのファイルが100のASCII文字を含んでいる場合、メモリ内で200バイトを消費します。
おそらく、この小さなデモンストレーションがあなたのために少し説明できるかもしれません。
ファイル全体を 'parcour'変数に格納しています。これは、多くの記憶を食べるでしょう。また、文字列にデータを追加するときに 'StringBuilder'を使うことを考えてください。 – ar34z
しかし、実際にはStringはそれほど多くのメモリを食べるべきではありませんか? StringBuilderを使用するとどのような利点がありますか?そして私はそれをどのように大まかに設定しますか? – Cyaena
私は、メモリ使用量を説明するのに適切な人ではありませんが、200 milを格納しています。メモリ内の文字はあまり有望ではない。ループ内で文字列を連結すると、 'StringBuilder'が高速になります。 2億回線で何をしようとしていますか?おそらく、これはあなたを助けることができます:http://stackoverflow.com/questions/10202905/is-it-advisable-to-store-large-strings-in-memory-or-repeatedly-read-a-fileメモリ使用量の詳細:http://www.javamex.com/tutorials/memory/string_memory_usage.shtml – ar34z