Integer、Longのリストはokを実行します。しかし、Stringを使用する場合、以下のコードは、最大でエントリがStringあたり8バイトの近傍になければならない場合、5GB以上のメモリを消費します。これは〜700MBにすぎません。また、無限に実行され、決してヒープをスローすることはありません。何が起こっている? String
の文字列のJavaメモリリーク?これが消費されてクラッシュする理由
List<List<String>> arrayList = new ArrayList<List<String>>();
long offset = 1000;
long size = 83886080;
int max = Integer.MAX_VALUE - 100;
long subloops = 1;
if(size > max)
{
subloops = size/max;
}
int temp = 0;
long count = 1;
long start = System.nanoTime();
for(int j=0; j<subloops; j++)
{
temp = (int)(size % max);
arrayList.add(new ArrayList<String>(temp));
List<String> holder = arrayList.get(j);
for (long i = 0; i < temp; i++)
{
holder.add(Long.toString(offset + count));
count++;
}
size -= temp;
}
long finalTime = System.nanoTime() - start;
System.out.println("Total time = " + finalTime);
System.out.println(count);
//for reference the max item length in bytes ends up being 8
System.out.println(Long.toString(offset+count).getBytes().length);
あなたは 'String'の基本メモリオーバーヘッドが少なくとも24バイトであることを知っていますか? –
文字列あたり8バイトですか? CompressedOopsを持つ64ビットJVMでは、文字列ごとに12バイトのヘッダーがあり、それぞれに16バイトのヘッダーを持つ 'char [] 'があります。文字列にはハッシュをキャッシュするためのintもあります。それは別の4バイトです。これはオーバーヘッドのオブジェクトあたり32バイトです。次に、各charは別の2バイトです。 – yshavit