Повышение производительности Java Hotspot VM: escape анализ

Escape анализ - это метод, с помощью которого Java HotSpot Server Compiler может анализировать область использования нового объекта и решать, следует ли размещать объект в куче Java.

Escape анализ поддерживается и включается по умолчанию в Java SE 6u23 и более поздних версиях.

Escape состояние объекта, основанное на escape анализе, может быть одним из следующих состояний:

  • GlobalEscape: объект экранирует метод и поток. Например, объект хранится в статическом поле, хранится в поле экранированного объекта или возвращается как результат текущего метода.
  • ArgEscape: объект передается в качестве аргумента или на него ссылается аргумент, но он не экранируется глобально во время вызова. Это состояние определяется путем анализа байт-кода вызываемого метода.
  • NoEscape: объект является скалярным заменяемым объектом, что означает, что его размещение может быть удалено из сгенерированного кода.

После escape анализа серверный компилятор исключает скалярные заменяемые выделения объектов и связанные блокировки из сгенерированного кода. Компилятор сервера также устраняет блокировки для объектов, которые глобально не экранируются. Он не заменяет выделение кучи выделением стека для объектов, которые глобально не экранируются.

Следующие примеры описывают некоторые сценарии для escape анализа:

1. Компилятор сервера может устранить определенные выделения объектов. Например, метод создает защитную копию объекта и возвращает копию вызывающей стороне.

public class Person {
  private String name;
  private int age;
  public Person(String personName, int personAge) {
    name = personName;
    age = personAge;
  }
        
  public Person(Person p) { this(p.getName(), p.getAge()); }
  public int getName() { return name; }
  public int getAge() { return age; }
}

public class Employee {
  private Person person;
  
  // делает защитную копию для защиты от изменений вызывающей стороной
  public Person getPerson() { return new Person(person) };
  
  public void printEmployeeDetail(Employee emp) {
    Person person = emp.getPerson();
    // этот вызывающий объект не изменяет объект, поэтому защитная копия не нужна
    System.out.println ("Employee's name: " + person.getName() + "; age: "  + person.getAge());     
  }
}

Метод создает копию, чтобы предотвратить изменение исходного объекта вызывающей стороной. Если компилятор определяет, что метод getPerson вызывается в цикле, тогда компилятор включает этот метод. С помощью escape-анализа, когда компилятор определяет, что исходный объект никогда не изменяется, компилятор может оптимизировать и исключить вызов для создания копии.

2. Компилятор сервера может устранить блоки синхронизации (исключение блокировки), если он определит, что объект является локальным для потока. Например, методы классов, таких как StringBuffer и Vector, синхронизируются, потому что к ним могут обращаться разные потоки. Однако в большинстве сценариев они используются локальным способом потока. В случаях, когда использование является локальным потоком, компилятор может оптимизировать и удалить блоки синхронизации.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки