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

时间:2015-07-12 16:03:36

标签: java jvm

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

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

的8Gb?

1 个答案:

答案 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*nLong个实例,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实现,您可以看到(假设您有足够的内存),您将不会遇到异常,但是大小会无声地溢出,因此可能在此之后很难使用此集合。