I read it in multiple places that using byte[] instead of string would save you memory. I wanted to test it out using jol.
Here my test:
public static void main (String[] args) throws java.lang.Exception{
System.out.println(VMSupport.vmDetails());
String StrByte = GraphLayout.parseInstance(sizeOfStrByteMap(100000)).toFootprint();
String ByteByte = GraphLayout.parseInstance(sizeOfByteByteMap(100000)).toFootprint();
String StrStr = GraphLayout.parseInstance(sizeOfStrStrMap(100000)).toFootprint();
System.out.println(StrByte);
System.out.println(ByteByte);
System.out.println(StrStr);
}
public static HashMap<String, String> sizeOfStrStrMap(int size) {
String value = "this is the sample value";
HashMap<String, String> map = new HashMap<>();
for (int i = 0; i < size; i++) {
map.putIfAbsent(Integer.toString(i), value);
}
return map;
}
public static HashMap<String, byte[]> sizeOfStrByteMap(int size) {
byte[] value = "this is the sample value".getBytes();
HashMap<String, byte[]> map = new HashMap<>();
for (int i = 0; i < size; i++) {
map.putIfAbsent(Integer.toString(i), value);
}
return map;
}
public static HashMap<byte[], byte[]> sizeOfByteByteMap(int size) {
byte[] value = "this is the sample value".getBytes();
HashMap<byte[], byte[]> map = new HashMap<>();
for (int i = 0; i < size; i++) {
map.putIfAbsent(Integer.toString(i).getBytes(), value);
}
return map;
}
Here is my result:
Running 64-bit HotSpot VM.
Using compressed oop with 3-bit shift.
Using compressed klass with 3-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
// StrByteMap
java.util.HashMap@15327b79d footprint:
COUNT AVG SUM DESCRIPTION
1 184 184 [B
100000 31 3120000 [C
1 1048592 1048592 [Ljava.util.HashMap$Node;
100000 24 2400000 java.lang.String
1 48 48 java.util.HashMap
100000 32 3200000 java.util.HashMap$Node
300003 9768824 (total)
// ByteByteMap
java.util.HashMap@a9d12ad footprint:
COUNT AVG SUM DESCRIPTION
100001 24 2400184 [B
1 1048592 1048592 [Ljava.util.HashMap$Node;
1 48 48 java.util.HashMap
100000 32 3200000 java.util.HashMap$Node
200003 6648824 (total)
// StrStrMap
java.util.HashMap@716d90fad footprint:
COUNT AVG SUM DESCRIPTION
100001 31 3120344 [C
1 1048592 1048592 [Ljava.util.HashMap$Node;
100001 24 2400024 java.lang.String
1 48 48 java.util.HashMap
100000 32 3200000 java.util.HashMap$Node
300004 9769008 (total)
As you can see, memory usage between StrByteMap and StrStrMap is almost identical. Am I testing it wrong here?
UPDATE: Please see @Amod Pandey's question below, I would also like to know why.
For Map test you are putting in the same value reference so it is not going to use much space. In the same way that you have a different key you need to make the values different or as you see, the choice of value type doesn't make much difference.