JohnWinter
JohnWinter

Reputation: 1023

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

What size of memory I will get if I will run this code?

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

8Gb?

Upvotes: 0

Views: 309

Answers (1)

Tagir Valeev
Tagir Valeev

Reputation: 100279

Such questions can be answered using the Java Object Layout tool. Here's the test code:

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());
            }
        }
    }
}

I have not enough memory to check 4_000_000_000 entries, but it's not necessary as LinkedList memory allocation is linear:

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)

So you practically have (48*n+32) bytes spent for n elements in the list, of which 24*n is Long instance, 24*n is internal LinkedList$Node instance and 32 is LinkedList itself. Thus the answer on your question would be 192_000_000_032 bytes... But this test was performed for small (<32Gb) -Xmx value when compressed oops work. For bigger amounts the numbers are different:

$ 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)

Thus in your case it's actually (64*n+48) bytes, namely 256_000_000_048 (roughly 256Gb).

Note that the results were obtained on Oracle JDK 1.8.0_40. It's not guaranteed that different JDK/JVM will produce the same result.

Also please note that normally Java collections cannot fit more than Integer.MAX_VALUE elements as size is stored in int. Looking into LinkedList implementation you can see that (assuming that you have enough memory) you will get no exception, but the size will silently overflow, thus probably it would be hard to work with this collection after that.

Upvotes: 3

Related Questions