Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带字符串的Java内存泄漏?为什么这是消费和崩溃_Java_String_Memory Leaks - Fatal编程技术网

带字符串的Java内存泄漏?为什么这是消费和崩溃

带字符串的Java内存泄漏?为什么这是消费和崩溃,java,string,memory-leaks,Java,String,Memory Leaks,整数、长、执行ok的列表。然而,当使用字符串时,下面的代码消耗超过5GB的内存,而一个条目最多应该在每个字符串8字节左右,相当于大约700MB。它还可以无限运行,从不将堆抛出边界。发生了什么事 List<List<String>> arrayList = new ArrayList<List<String>>(); long offset = 1000; long size = 83886080;

整数、长、执行ok的列表。然而,当使用字符串时,下面的代码消耗超过5GB的内存,而一个条目最多应该在每个字符串8字节左右,相当于大约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);
List arrayList=new arrayList();
长偏移=1000;
长尺寸=83886080;
int max=Integer.max_值-100;
长子循环=1;
如果(尺寸>最大值)
{
子循环=大小/最大值;
}
内部温度=0;
长计数=1;
长启动=System.nanoTime();

对于(int j=0;j字符串
的内存占用包括对象的内存开销加上对象的字段。有关详细信息,请参阅此答案:

Java 8中的
字符串
对象有两个实例字段:

  • char值[]
  • int散列
假设64位Java带有压缩的OOPS,这意味着内存是:

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个字节


创建83886080个字符串然后使用5033164800字节=4.7GB

您知道
字符串的基本内存开销是,在64位JVM上,使用CompressedOops,至少24个字节?每个字符串8个字节?您可以查看每个字符串12个字节的头,每个头都有一个
char[]
有16个字节的头。字符串也有一个int来缓存它们的哈希,即另外4个字节。这是每个对象的32个字节,只是开销。然后每个字符是另外2个字节。