First of all, I would like to create an array of primitives and Box type and see how much memory is used.
private static final int NUM = 100_000;
public static void main(String[] args) {
long beforeUse, afterUse, div;
beforeUse = memoryUsed();
int[] primitive = new int[NUM];
afterUse = memoryUsed();
div = afterUse - beforeUse;
out.println(" -- int[] -- ");
out.println(div);
out.println((double)div / primitive.length);
beforeUse = memoryUsed();
Integer[] classes = new Integer[NUM];
afterUse = memoryUsed();
div = afterUse - beforeUse;
out.println(" -- Integer[] unset -- ");
out.println(div);
out.println((double)div / classes.length);
for (int i = 0;i < classes.length;i++) {
classes[i] = i;
}
afterUse = memoryUsed();
div = afterUse - beforeUse;
out.println(" -- Integer[] set -- ");
out.println(div);
out.println((double)div / classes.length);
}
Execution result
-- boolean[] --
100016
1.00016
-- Boolean[] unset --
400016
4.00016
-- Boolean[] set --
400016
4.00016
-- byte[] --
100016
1.00016
-- Byte[] unset --
400016
4.00016
-- Byte[] set --
448528
4.48528
-- short[] --
200016
2.00016
-- Short[] unset --
400016
4.00016
-- Short[] set --
1923440
19.2344
-- char[] --
200016
2.00016
-- Character[] unset --
400016
4.00016
-- Character[] set --
2402512
24.02512
-- int[] --
400016
4.00016
-- Integer[] unset --
400016
4.00016
-- Integer[] set --
2202512
22.02512
-- long[] --
1048576
10.48576
-- Long[] unset --
400016
4.00016
-- Long[] set --
3105872
31.05872
-- float[] --
400016
4.00016
-- Float[] unset --
400016
4.00016
-- Float[] set --
2706352
27.06352
-- double[] --
1048576
10.48576
-- Double[] unset --
400016
4.00016
-- Double[] set --
3651112
36.51112
Mold | Primitive | BoxMold(unset) | BoxMold(set) |
---|---|---|---|
boolean / Boolean | 1.00 | 4.00 | 4.00 |
byte / Byte | 1.00 | 4.00 | 4.48 |
short / Short | 2.00 | 4.00 | 19.23 |
char / Character | 2.00 | 4.00 | 24.03 |
int / Integer | 4.00 | 4.00 | 27.06 |
long / Long | 10.49 | 4.00 | 36.51 |
float / Float | 4.00 | 4.00 | 27.06 |
double / Double | 10.49 | 4.00 | 31.06 |
When I create an array, I always use 16 bytes. I'm not sure that the primitives used more memory than long and double expected. Box type (set) uses 20 bytes or more after Character, so heavy use is strictly prohibited.
Let's take a look at the memory usage of the String class.
// set empty
for (int i = 0;i < NUM;i++) {
ary[i] = "";
}
// set new String
for (int i = 0;i < NUM;i++) {
ary[i] = new String();
}
// set 10digit
for (int i = 0;i < NUM;i++) {
ary[i] = new String("0123456789");
}
-- String[] unset --
400016
4.00016
-- String[] set empty --
400016
4.00016
-- String[] set new String --
3105872
31.05872
-- String[] set 10digit --
3105872
31.05872
New String
for all elements consumes about 31 bytes. However, it is strange that even new String ("0123456789 ")
is 31 bytes.
Is it because the internal element private final byte [] value;
is always the same reference?
So I fixed it so that all the elements are unique.
for (int i = 0;i < NUM;i++) {
ary[i] = String.format("%010d", i);
}
System.gc();
-- String[] set 10digit --
4998968
49.98968
It became 49 bytes per element.
HashMap
Put 100,000 elements in HashMap.
Map<String, String> map = new HashMap<>();
for (int i = 0;i < NUM;i++) {
map.put(String.valueOf(i), "A" + i);
}
13632176
136.32176
It became 136 bytes per element. It seems that you need to read it because you can not understand the rationale unless you look at the implementation.
Recommended Posts