整数列表,长,执行正常。但是当使用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);
答案 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 。