使用字符串的Java内存泄漏?为什么这会消耗和崩溃

时间:2016-10-12 04:15:06

标签: java string memory-leaks

整数列表,长,执行正常。但是当使用String时,如果一个条目最多应该在每个字符串8个字节的邻域中,则下面的代码消耗超过5GB的内存,相当于仅约700MB。它也无限运行,永远不会抛出堆出界限。发生了什么事?

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

1 个答案:

答案 0 :(得分:3)

String的内存占用涉及对象的内存开销加上对象的字段。有关详细信息,请参阅此答案:What is the memory consumption of an object in Java?

String对象在Java 8中有两个实例字段:

  • char value[]
  • int hash

假设使用压缩OOPS的64位Java,这意味着内存是:

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

为字符串的引用添加另外4个字节(存储在ArrayList中),并获得8个字符的字符串总大小: 60个字节

创建83,886,080个字符串然后使用5,033,164,800字节= 4.7 Gb