У меня iMac 2010 года с 8 ГБ оперативной памяти, работающий под управлением Eclipse Neon.2 Release (4.6.2) с Java 1.8.0_25. С аргументом VM -Xmx6g я запустил следующий код:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
try {
sb.append('a');
} catch (Throwable e) {
System.out.println(i);
break;
}
}
System.out.println(sb.toString().length());
Это печатает:
Requested array size exceeds VM limit
1207959550
Итак, максимальный размер массива составляет ~ 1 207 959 549. Затем я понял, что нам на самом деле все равно, не хватает ли Java памяти: мы просто ищем максимальный размер массива (который, кажется, где-то определен как постоянная) Итак:
for (int i = 0; i < 1_000; i++) {
try {
char[] array = new char[Integer.MAX_VALUE - i];
Arrays.fill(array, 'a');
String string = new String(array);
System.out.println(string.length());
} catch (Throwable e) {
System.out.println(e.getMessage());
System.out.println("Last: " + (Integer.MAX_VALUE - i));
System.out.println("Last: " + i);
}
}
Какие отпечатки:
Requested array size exceeds VM limit
Last: 2147483647
Last: 0
Requested array size exceeds VM limit
Last: 2147483646
Last: 1
Java heap space
Last: 2147483645
Last: 2
Так что, кажется, максимум - Integer.MAX_VALUE - 2 или (2 ^ 31) - 3
P.S. Я не уверен, почему мой StringBuilder
увеличился до 1207959550
, а мой char[]
- до (2 ^ 31) -3. Кажется, что AbstractStringBuilder
удваивает размер своего внутреннего char[]
, чтобы увеличить его, что, вероятно, вызывает проблему.