Использование строки против байта [] в качестве значения, Использование памяти в карте
Я прочитал это в нескольких местах, что использование байта [] вместо строки сэкономит вам память. Я хотел проверить это с помощью JOL.
Вот мой тест:
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;
}
Вот мой результат:
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)
Как видите, использование памяти между StrByteMap и StrStrMap практически одинаково. Я проверяю это неправильно здесь?
ОБНОВЛЕНИЕ: Пожалуйста, смотрите вопрос @ Амода Пандея ниже, я также хотел бы знать, почему.
2 ответа
Для теста Map вы указываете ту же ссылку, поэтому она не займет много места. Точно так же, как у вас есть другой ключ, вам нужно изменить значения или, как вы видите, выбор типа значения не имеет большого значения.
Я нахожу это странным.
// StrByteMap
java.util.HashMap@15327b79d footprint:
COUNT AVG SUM DESCRIPTION
1 184 184 [B
100000 31 3120000 [C
Существует один экземпляр байтового массива и 100000 экземпляров массива char. Который является массивом 100001 в случае StrStr
// StrStrMap
java.util.HashMap@716d90fad footprint:
COUNT AVG SUM DESCRIPTION
100001 31 3120344 [C
Таким образом, даже если вы сохранили байтовый массив, объем памяти занимает массив символов!!
Другим моментом для ByteByte является то, что средний размер объекта байтового массива равен 24, что меньше размера байтового массива 184 (StrByteMap), и общее число не должно совпадать во всех трех случаях.