Как позволить PSOldGen расширяться для размещения очень больших объектов? - PullRequest
3 голосов
/ 24 ноября 2010

У меня есть программа, которой нужно выделить пространство кучи для одного очень большого объекта, но я обнаружил, что получаю 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 позволить старому поколению расти больше, чем кажется по умолчанию?

1 Ответ

3 голосов
/ 24 ноября 2010

Вы можете использовать NewRatio, NewSize, MaxNewSize и SurvivorRatio, чтобы настроить размер Молодое поколение , таким образом косвенно также настраивая размер Старое поколение .

Кроме того, если вас беспокоит, что Permanent Generation использует слишком много памяти, вы можете настроить это с помощью опции MaxPermSize командной строки.

См. Настройка сборки мусора с виртуальной машиной Java [tm] 5.0 * для получения более подробной информации, особенно части о поколениях .

Например, установка максимального размера Young Generation на 10M позволяет успешно запустить пример программы:

java -Xmx40M -XX:+PrintGCDetails -XX:MaxNewSize=10M HeapTest 28000000

выдает на моей машине следующий вывод:

26
28000000
Heap
 par new generation   total 9216K, used 1499K [106810000, 107210000, 107210000)
  eden space 8192K,  18% used [106810000, 106986ed0, 107010000)
  from space 1024K,   0% used [107010000, 107010000, 107110000)
  to   space 1024K,   0% used [107110000, 107110000, 107210000)
 concurrent mark-sweep generation total 30720K, used 27343K [107210000, 109010000, 109010000)
 concurrent-mark-sweep perm gen total 21248K, used 4501K [109010000, 10a4d0000, 10e410000)
...