У меня есть программа, которой нужно выделить пространство кучи для одного очень большого объекта, но я обнаружил, что получаю OutOfMemoryException
s, когда оказывается, что свободной кучи намного больше, чем требуется для этого большого объекта.
Эта тестовая программа демонстрирует проблему:
public class HeapTest {
public static void main(String[] args) {
final int size = Integer.parseInt(args[0]);
System.out.println(size >> 20);
final byte[] buf = new byte[size];
System.out.println(buf.length);
}
}
Если я запускаю ее как java -Xmx40M -XX:+PrintGCDetails HeapTest 28000000
, я получаю следующий вывод:
26
[GC [PSYoungGen: 317K->176K(9216K)] 317K->176K(36544K), 0.0007430 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 176K->144K(9216K)] 176K->144K(36544K), 0.0004650 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen: 144K->0K(9216K)] [PSOldGen: 0K->115K(9216K)] 144K->115K(18432K) [PSPermGen: 2710K->2710K(21248K)], 0.0053960 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC [PSYoungGen: 0K->0K(9216K)] 115K->115K(36544K), 0.0002010 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen: 0K->0K(9216K)] [PSOldGen: 115K->112K(15104K)] 115K->112K(24320K) [PSPermGen: 2710K->2708K(21248K)], 0.0078150 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at HeapTest.main(HeapTest.java:5)
Heap
PSYoungGen total 9216K, used 476K [0x00000000ff2b0000, 0x0000000100000000, 0x0000000100000000)
eden space 7936K, 6% used [0x00000000ff2b0000,0x00000000ff327190,0x00000000ffa70000)
from space 1280K, 0% used [0x00000000ffa70000,0x00000000ffa70000,0x00000000ffbb0000)
to space 1280K, 0% used [0x00000000ffec0000,0x00000000ffec0000,0x0000000100000000)
PSOldGen total 27328K, used 112K [0x00000000fd800000, 0x00000000ff2b0000, 0x00000000ff2b0000)
object space 27328K, 0% used [0x00000000fd800000,0x00000000fd81c378,0x00000000ff2b0000)
PSPermGen total 21248K, used 2815K [0x00000000f3000000, 0x00000000f44c0000, 0x00000000fd800000)
object space 21248K, 13% used [0x00000000f3000000,0x00000000f32bff48,0x00000000f44c0000)
Массив, который я пытаюсь выполнитьcreate должен быть около 27344K, что немного превышает размер пространства объектов PSOldGen.Однако общее неиспользуемое пространство составляет около 54000 КБ, что почти вдвое больше, чем необходимо для моего массива.Поскольку моя (настоящая) программа работает с массивом на месте, она использует практически любую память сверх той, которая требуется для массива, поэтому выделение в два раза больше необходимой мне памяти и использование только половины из этого представляется бесполезным.
Есть лиспособ, которым я могу убедить JVM позволить старому поколению расти больше, чем кажется по умолчанию?