2016-10-12 7 views
1

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); 
+0

あなたは 'String'の基本メモリオーバーヘッドが少なくとも24バイトであることを知っていますか? –

+3

文字列あたり8バイトですか? CompressedOopsを持つ64ビットJVMでは、文字列ごとに12バイトのヘッダーがあり、それぞれに16バイトのヘッダーを持つ 'char [] 'があります。文字列にはハッシュをキャッシュするためのintもあります。それは別の4バイトです。これはオーバーヘッドのオブジェクトあたり32バイトです。次に、各charは別の2バイトです。 – yshavit

答えて

3

メモリフットプリントは、オブジェクトのメモリオーバーヘッドを加えたオブジェクトのフィールドを含みます。詳細については、この回答を参照してくださいWhat is the memory consumption of an object in Java?

Stringオブジェクトは、Java 8内の2つのインスタンスのフィールドを有する:

OOPS圧縮し、その手段を備えた64ビットJavaを仮定
  • char value[]
  • int hash

メモリは:

String: 
    Object header:   12 bytes 
    Reference to char[]: + 4 bytes 
    Integer value:  + 4 bytes 
    Data size:   = 20 bytes 
    Total aligned size: 24 bytes 
char[]: 
    Object header:   12 bytes 
    Array length:  + 4 bytes 
    Characters:   + 2 bytes * length 
    Data size (len=8): = 32 bytes 
    Total aligned size: 32 bytes 

は(ArrayListに格納されている)の文字列を参照するために、別の4つのバイトを追加し、あなたは、8文字の文字列の合計サイズを取得:その後、5033164800バイトを使用しています83886080個の文字列を作成

60バイト= 4.7Gb