如果我将 运行 我的代码,我将获得多少内存?

How much memory I'll get If I'll run my code?

如果我将 运行 这段代码,我将获得多少内存?

List<Long> list = new LinkedList<>();
for (long i = 0; i < 4_000_000_000L; i++) {
    list.add(i);
}

8Gb?

此类问题可以使用 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*nLong 个实例,24*n 是内部 LinkedList$Node 实例和 32LinkedList 本身。因此,您的问题的答案是 192_000_000_032 bytes... 但是此测试是在 compressed oops 工作时针对较小的 (<32Gb) -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) 字节,即 256_000_000_048(大约 256Gb)。

请注意,结果是在 Oracle JDK 1.8.0_40 上获得的。不能保证不同的 JDK/JVM 会产生相同的结果。

另请注意,通常 Java 集合不能容纳超过 Integer.MAX_VALUE 个元素,因为大小存储在 int 中。查看 LinkedList 实现你可以看到(假设你有足够的内存)你不会得到异常,但是大小会悄悄溢出,因此之后可能很难使用这个集合。