Integer() 到底有多大?我问是因为下面发生了什么。
在尝试将 10^6 个整数(在 [0, 10^6) 中)放入双端队列后,我用完了堆内存。该实现使用双向链表并显示为
Deque<Item> implements Iterable<Item> { }
但是当使用字符串时,我能够完成而不必增加堆的大小:
String hw = "Hello, world.";
for (i=0;i<10**6;i++) {
myDq.addToEnd(hw);
}
Integer() 到底有多大?我问是因为下面发生了什么。
在尝试将 10^6 个整数(在 [0, 10^6) 中)放入双端队列后,我用完了堆内存。该实现使用双向链表并显示为
Deque<Item> implements Iterable<Item> { }
但是当使用字符串时,我能够完成而不必增加堆的大小:
String hw = "Hello, world.";
for (i=0;i<10**6;i++) {
myDq.addToEnd(hw);
}
hw
总是引用同一个对象,所以即使你添加了 10^6 个项目(因此在内部有 ~10^6 个节点),你也只会String
分配一个对象——很多对那个对象的引用,但只是那一个对象。
事实上,即使你做了类似的事情:
for (i=0;i<10**6;i++) {
String hs = "Hello, world."
myDq.addToEnd(hw);
}
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 无处可去以获得更多堆空间。)