1

Lists of Integer, Long, execute ok. However when using String the code below consumes over 5GB of memory when an entry at most should be in the neighborhood of 8 bytes per String, equating to only ~700MB. It also runs infinitely never throwing heap out of bounds. What is going on?

        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);
Tarek Z
  • 55
  • 6
  • You know the base memory overhead of a `String` is, like, at least 24 bytes? – Louis Wasserman Oct 12 '16 at 04:18
  • 3
    8 bytes per String? On 64bit JVM with CompressedOops, you'ree looking at 12 bytes of header per String, and each one of those has a `char[]` with 16 bytes of header. Strings also have an int to cache their hash, that's another 4 bytes. That's 32 bytes per object just of overhead. Then each char is another 2 bytes. – yshavit Oct 12 '16 at 04:24

1 Answers1

3

Memory footprint of a String involves the memory overhead of an object plus the fields of the object. See this answer for detail: What is the memory consumption of an object in Java?

The String object has two instance fields in Java 8:

  • char value[]
  • int hash

Assuming 64-bit Java with compressed OOPS, that means memory is:

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

Add another 4 bytes for the reference to the string (stored in the ArrayList), and you get a total size for String of 8 characters: 60 bytes

Creating 83,886,080 strings then uses 5,033,164,800 bytes = 4.7 Gb.

Community
  • 1
  • 1
Andreas
  • 154,647
  • 11
  • 152
  • 247