Массивами байтов small я называю массивы байтов длиной от 10 до 30.
В магазине я имею в виду сохранение в ОЗУ, а не сериализацию и сохранение файловой системы.
Система macOS 10.12.6, Oracle jdk1.8.0_141 64bit, JVM args -Xmx1g
Пример:
Ожидаемое поведение для new byte[200 * 1024 * 1024]
составляет ≈200 мб кучного пространства
public static final int TARGET_SIZE = 200 * 1024 * 1024;
public static void main(String[] args) throws InterruptedException {
byte[] arr = new byte[TARGET_SIZE];
System.gc();
System.out.println("Array size: " + arr.length);
System.out.println("HeapSize: " + Runtime.getRuntime().totalMemory());
Thread.sleep(60000);
}
Однако для меньших массивов математика не так проста
public static final int TARGET_SIZE = 200 * 1024 * 1024;
public static void main(String[] args) throws InterruptedException {
final int oneArraySize = 20;
final int numberOfArrays = TARGET_SIZE / oneArraySize;
byte[][] arrays = new byte[numberOfArrays][];
for (int i = 0; i < numberOfArrays; i++) {
arrays[i] = new byte[oneArraySize];
}
System.gc();
System.out.println("Arrays size: " + arrays.length);
System.out.println("HeapSize: " + Runtime.getRuntime().totalMemory());
Thread.sleep(60000);
}
И еще хуже
Вопрос
Откуда возникают служебные данные? Как эффективно хранить и работать с малыми массивами (куски данных)?
Обновление 1
для new byte[200*1024*1024][1]
он ест
Базовая математика говорит, что new byte[1]
весит 24 байта.
Обновление 2
В соответствии с Каково потребление памяти объектом в Java?
минимальный размер объекта в Java составляет 16 байт. Из моих предыдущих "измерений" 24 байта -4 байта для int length -1 фактический байт моих данных = 3 байта некоторого дополнения other garbage.