如果我运行此代码,我将获得多大的内存?
List<Long> list = new LinkedList<>();
for (long i = 0; i < 4_000_000_000L; i++) {
list.add(i);
}
的8Gb?
答案 0 :(得分:3)
可以使用Java Object Layout工具回答此类问题。这是测试代码:
import org.openjdk.jol.info.GraphLayout;
import org.openjdk.jol.util.VMSupport;
import java.util.*;
public class JOLTest {
public static void main(String[] args) throws Exception {
List<Long> list = new LinkedList<>();
for (long i = 0; i < 4000L; i++) {
list.add(i);
if((i+1) % 1000 == 0) {
System.out.println("i = "+(i+1));
System.out.println(GraphLayout.parseInstance(list).toFootprint());
}
}
}
}
我没有足够的内存来检查4_000_000_000个条目,但由于LinkedList
内存分配是线性的,所以没有必要:
i = 1000
java.util.LinkedList@41a4555ed footprint:
COUNT AVG SUM DESCRIPTION
1000 24 24000 java.lang.Long
1 32 32 java.util.LinkedList
1000 24 24000 java.util.LinkedList$Node
2001 48032 (total)
i = 2000
java.util.LinkedList@41a4555ed footprint:
COUNT AVG SUM DESCRIPTION
2000 24 48000 java.lang.Long
1 32 32 java.util.LinkedList
2000 24 48000 java.util.LinkedList$Node
4001 96032 (total)
i = 3000
java.util.LinkedList@41a4555ed footprint:
COUNT AVG SUM DESCRIPTION
3000 24 72000 java.lang.Long
1 32 32 java.util.LinkedList
3000 24 72000 java.util.LinkedList$Node
6001 144032 (total)
i = 4000
java.util.LinkedList@41a4555ed footprint:
COUNT AVG SUM DESCRIPTION
4000 24 96000 java.lang.Long
1 32 32 java.util.LinkedList
4000 24 96000 java.util.LinkedList$Node
8001 192032 (total)
因此,您在列表中的(48*n+32)
元素实际上花费了n
个字节,其中24*n
为Long
个实例,24*n
为内部{{1}实例和LinkedList$Node
本身就是32
。因此,您的问题的答案是LinkedList
......但是当compressed oops工作时,此测试是针对小(<32Gb)192_000_000_032 bytes
值执行的。对于更大的数量,数字是不同的:
-Xmx
因此,在您的情况下,它实际上是$ java -Xmx32G -cp test-1.0.jar JOLTest
i = 1000
java.util.LinkedList@41a4555ed footprint:
COUNT AVG SUM DESCRIPTION
1000 24 24000 java.lang.Long
1 48 48 java.util.LinkedList
1000 40 40000 java.util.LinkedList$Node
2001 64048 (total)
i = 2000
java.util.LinkedList@41a4555ed footprint:
COUNT AVG SUM DESCRIPTION
2000 24 48000 java.lang.Long
1 48 48 java.util.LinkedList
2000 40 80000 java.util.LinkedList$Node
4001 128048 (total)
i = 3000
java.util.LinkedList@41a4555ed footprint:
COUNT AVG SUM DESCRIPTION
3000 24 72000 java.lang.Long
1 48 48 java.util.LinkedList
3000 40 120000 java.util.LinkedList$Node
6001 192048 (total)
i = 4000
java.util.LinkedList@41a4555ed footprint:
COUNT AVG SUM DESCRIPTION
4000 24 96000 java.lang.Long
1 48 48 java.util.LinkedList
4000 40 160000 java.util.LinkedList$Node
8001 256048 (total)
个字节,即(64*n+48)
(大约256Gb)。
请注意,结果是在Oracle JDK 1.8.0_40上获得的。不能保证不同的JDK / JVM会产生相同的结果。
另请注意,通常Java集合不能超过256_000_000_048
元素,因为大小存储在Integer.MAX_VALUE
中。查看int
实现,您可以看到(假设您有足够的内存),您将不会遇到异常,但是大小会无声地溢出,因此可能在此之后很难使用此集合。