整数()有多大?我问因为下面发生了什么。
在尝试将10 ^ 6个整数(在[0,10 ^ 6)中)放入双端队列后,我的堆内存耗尽。该实现使用双向链表并显示为
Deque<Item> implements Iterable<Item> { }
但是当使用Strings时,我能够完成而不必增加堆的大小:
String hw = "Hello, world.";
for (i=0;i<10**6;i++) {
myDq.addToEnd(hw);
}
答案 0 :(得分:9)
hw
总是引用同一个对象,所以即使你要添加10 ^ 6个项目(因此内部有~10 ^ 6个节点),你只会有一个String
个对象已分配 - 对该对象的大量引用,但仅包含该对象。
事实上,即使你做了类似的事情:
for (i=0;i<10**6;i++) {
String hs = "Hello, world."
myDq.addToEnd(hw);
}
由于string interning,您只有一个String
:整个JVM中所有相等的字符串文字都使用相同的一个String
对象。
我怀疑如果你把它改成一点,你会得到同样的OOM:
for (i=0;i<10**6;i++) {
String hs = new String("Hello, world.".toCharArray());
myDq.addToEnd(hw);
}
每次分配一个新的String
,并带有原始String
的char数组的副本。
(OOM是OutOfMemoryError
的常见昵称,这是Java在堆空间用完时抛出的,无法通过垃圾收集器(GC)回收。在这种情况下,列表和所有通过它可以访问的对象 - 内部节点对象,Integer
或String
值等 - 程序仍然可以访问,因此无法进行GC,因此JVM具有无处可寻求更多的堆空间。)