Reputation: 1023
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
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