Есть ли ограничение на выделение массива char в Java
Что проверяют
Понимаете ли вы, откуда берутся пределы: из языка, из конкретной JVM и из размера кучи. Следом обычно спрашивают, сколько памяти займёт такой массив и что делать, если данных больше.
Как отвечать
Ограничений три, их стоит развести:
- язык: длина массива имеет тип
int, поэтому теоретический максимумInteger.MAX_VALUE, около 2,1 млрд элементов. Отрицательный размер даётNegativeArraySizeException; - JVM: HotSpot не даёт выделить массив ровно на
Integer.MAX_VALUE, часть места съедает заголовок объекта. Запрос сверх предела падает сOutOfMemoryError: Requested array size exceeds VM limitдаже при огромной куче. Сам JDK страхуется и растит внутренние массивы не дальшеInteger.MAX_VALUE - 8, это константаSOFT_MAX_ARRAY_LENGTHво внутреннем классеArraysSupport; - куча:
charзанимает 2 байта, поэтому массив максимальной длины весит около 4 ГБ. Если-Xmxменьше, получите обычныйOutOfMemoryError: Java heap space.
Хорошо добавить про сборщик мусора. В G1 объект больше половины региона считается humongous и требует непрерывной цепочки регионов. Большой массив может не выделиться при формально свободной памяти, а частые такие выделения провоцируют лишние сборки.
Связанная деталь про строки: с Java 9 String хранит не char[], а byte[] с кодировкой LATIN1 или UTF16 (compact strings). Для строки в UTF16 предел длины вдвое меньше, StringBuilder упирается в те же ограничения.
Что делать с данными, которые не помещаются: резать на куски и обрабатывать потоково через Reader, отображать файл в память частями, работать вне кучи через Foreign Function & Memory API (финальный с Java 22), где MemorySegment адресуется long.
Где спотыкаются
Советуют взять ArrayList<Character>. Внутри у него массив с тем же пределом int, а вместо двух байт на символ хранится ссылка на Character, так что памяти уйдёт в разы больше.
Называют точное число вроде «ровно Integer.MAX_VALUE». Точный предел зависит от JVM и типа элемента, честный ответ: чуть меньше Integer.MAX_VALUE.
Путают два вида OutOfMemoryError. «Requested array size exceeds VM limit» увеличением -Xmx не лечится, «Java heap space» лечится.