Есть ли различия в распределении памяти между Java 8 и Java 9? - PullRequest
0 голосов
/ 26 августа 2018

Я хотел поэкспериментировать с опцией -Xmx в Java и создал простую тестовую программу, которая выделяет 1 Mib за раз, пока не заканчивается память.

import java.util.Vector;

public class MemoryMuncher {
    static final int MiB = 1048576;
    static final int accellerator = 1;

    public static void main(String[] args) {
        Vector victor = new Vector();
        int i = 1;
        try {
            while (true) {
                byte roger[] = new byte[MiB * accellerator];
                victor.add(roger);
                Runtime rt = Runtime.getRuntime();
                System.out.printf("free: %,6d\t\ttotal: %,6d\t\tallocated: %,6d \n", rt.freeMemory()/MiB, rt.totalMemory()/MiB, i++*accellerator);
            }
        } catch (OutOfMemoryError e) {
            System.out.println(e);
        }
    }
}

Когда я запускаю программу с параметром -Xmx, я замечаю разницу в поведении между Java 8 (1.8.0.131) и Java 9 (9.0.1).

Java 8 работает близко к тому, что я ожидал. Когда я запускаю программу с -Xmx256M, она выделяет 233 МБ, прежде чем выдать ошибку OutOfMemoryError.

free:    361        total:    368       allocated:      1 
free:    360        total:    368       allocated:      2 
...
free:     12        total:    245       allocated:    232 
free:     11        total:    245       allocated:    233 
java.lang.OutOfMemoryError: Java heap space

Однако, когда я запускаю ту же программу с Java 9 , она получает примерно на полпути (127 МБ), прежде чем получит исключение. Это соответствует. Если я изменю значение -Xmx на 512M или 1024M, оно получит только половину этой суммы (255 МБ и 510 МБ соответственно). У меня нет объяснения этому поведению.

free:    250        total:    256       allocated:      1 
free:    247        total:    256       allocated:      2 
...
free:      2        total:    256       allocated:    126 
free:      1        total:    256       allocated:    127 
java.lang.OutOfMemoryError: Java heap space

Я искал в документации любые изменения в управлении памятью между Java 8 и Java 9, но ничего не нашел.

Кто-нибудь знает, почему Java 9 будет управлять / выделять память в некоторых случаях по сравнению с предыдущими версиями Java?

1 Ответ

0 голосов
/ 26 августа 2018

Я нашел эту очень интересную статью о том, как Java 9 планировала собирать мусор по-разному.

В частности, Java 9 планирует использовать сборщик мусора G1, который делит память на фиксированные размеры. То, что может делать ваш код, - это запускать разделение памяти на два блока фиксированного размера для Java 9. Причина этого заключается в том, что он сэкономит другую половину памяти для перемещения всего и «сжатия» памяти, которая все еще используется. Тем не менее, поскольку вы просто продолжаете использовать память, она сразу же сломается, когда ~ 1/2 памяти будет использована. Я не уверен, насколько строгой может быть ваша CS, но в моей школе мы изучали простые методы сбора мусора, и одна из таких простых, о которых G1GC напоминает мне, - это метод stop-and-copy , который переключает выделенная память между половинами памяти, в то время как она «сжимает» память при этом.

В Java 8 используется Parallel Collector, который отличается от G1GC, так как все, что ему нужно, - это пропускная способность. Таким образом, будет использовано ближе к 100% истинной кучи за счет увеличения времени GC. Конечно, это компромисс между двумя версиями, но вы можете обойти это, явно указав тип GC для использования. Например, если в Java 9 вы используете опцию:

-XX:UseParallelGC

вы должны увидеть то же поведение, что и в Java 8. В статье, на которую я ссылаюсь, есть все разные варианты, но я думаю, вы поняли идею. Надеюсь, что это поможет / ответит на ваш вопрос, я на самом деле не осознавал этого, пока вы не подняли его, поэтому спасибо, что сообщили мне об этом.

РЕДАКТИРОВАТЬ: Согласно самим Oracle , они говорят, что новый сборщик мусора G1 предназначен для машин с большим объемом памяти, опять же объясняя причину, почему они не будут использовать пространство полной кучи для тратить меньше времени на GC-ing.

...