带字符串的Java内存泄漏?为什么这是消费和崩溃
整数、长、执行ok的列表。然而,当使用字符串时,下面的代码消耗超过5GB的内存,而一个条目最多应该在每个字符串8字节左右,相当于大约700MB。它还可以无限运行,从不将堆抛出边界。发生了什么事带字符串的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;
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个字节。