почему этот код Java не может использовать escape-анализ? - PullRequest
2 голосов
/ 03 ноября 2019

мой код здесь =>

class PointHolder {
    private Point point;

    public PointHolder(Point point) {
        this.point = point;
    }
    //getter
}
class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    //getter setter
}

public class Escape {
    public static void main(String[] args) {
        for (int i = 0; i < 20000; i++) {
            test4(i);
        }
    }
    static int foo;
    public static void test4(int x) {
        PointHolder pointHolder = new PointHolder(new Point(x + 2, 42));
        foo = pointHolder.getPoint().getX();
    }
}

используйте jitwatch, я мог видеть, что pointHolder не выделен, но new Point(x+2, 42) все еще выделен.

ea

es2

Я не мог понять, почему

1 Ответ

0 голосов
/ 04 ноября 2019

Анализ побега в компиляторе HotSpot C2 довольно прост. Он никогда не пытался обнаружить всех возможных объектов, которые не выходят за рамки компиляции. В частности, в настоящее время он не обрабатывает многоуровневое дерево ссылок.

В вашем примере ссылка на недавно выделенный Point назначена полю объекта: PointHolder.point. JIT рассматривает это назначение как экранирование объекта Point и, таким образом, не устраняет выделение.

Одним конкретным исключением является бокс-распаковка: HotSpot специально обрабатывает методы упаковки-распаковки. Например, он по-прежнему сможет исключить выделение объекта Integer, если он назначен полю IntegerHolder.

Хотя эта проблема не является чем-то неразрешимой - это скорее упущенная возможность оптимизации. Graal JIT лучше в этом смысле - в данном примере он исключает устранение как Point, так и PointHolder распределений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...