Массивами байтов 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]
он ест
![образец памяти jvisualvm для 200 * 1024 * 1024 нового байта [1]](/img/f3c1107429cfb89602c4457e132c0d8d.png)
Базовая математика говорит, что new byte[1] весит 24 байта.
Обновление 2
В соответствии с Каково потребление памяти объектом в Java?
минимальный размер объекта в Java составляет 16 байт. Из моих предыдущих "измерений" 24 байта -4 байта для int length -1 фактический байт моих данных = 3 байта некоторого дополнения other garbage.
![jvisualvm общая куча использования кучи для нового байта [200 * 1024 * 1024]](/img/c9165ba7ea79b24432fb49e5a47fa27c.png)
![образец памяти jvisualvm новый байт [200 * 1024 * 1024]](/img/3ad3de3a3dcd6f276054eb576c52e399.png)
![jvisualvm общая куча использования кучи для 10 * 1024 * 1024 нового байта [20]](/img/3897d659d9d617b4638b24a2138e0e6f.png)
![образец памяти jvisualvm для 10 * 1024 * 1024 нового байта [20]](/img/ce65386d0ff9d46ef4666562b211a6f5.png)
![jvisualvm общая куча использования кучи для 20 * 1024 * 1024 нового байта [10]](/img/177d8541ddc0a9ef8056f8cc5087a898.png)
![образец памяти jvisualvm для 20 * 1024 * 1024 нового байта [10]](/img/6c90b596f7230fde0a5a32d173419881.png)