Java Escape-анализ не работает
Для приведенного ниже кода, я вижу много активности GC. Насколько я понимаю, это подходящий сценарий для EA. Почему EA не эффективна. DummyObject не имеет внутри ничего выделенного. Используемые параметры JVM: -server, -verbosegc.
static void anayzeEA()
{
for(int i = 0 ; i < 100000000; i++) {
DummyObject obj = new DummyObject();
if(obj.hashCode() == 97787) { //to prevent the obj being optimized
System.out.println(obj.hashCode());
}
}
}
3 ответа
См. Связанные вопросы и ответы здесь, в которых предлагается, что вы можете загрузить отладочный JDK и использовать параметры командной строки: -XX:+UnlockDiagnosticVMOptions -XX:+PrintEscapeAnalysis -XX:+PrintEliminateAllocations
распечатать события анализа побега, как они происходят.
Java API говорит:
Насколько это практически целесообразно, метод hashCode, определенный классом Object, возвращает разные целые числа для разных объектов. (Это обычно реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуется языком программирования JavaTM.)
Таким образом, вы генерируете объекты, производите непредсказуемые хэш-коды для каждого и сравниваете их с некоторым значением. Дополнительно это нативный метод, поэтому JIT не знает, что происходит внутри.
Анализ побега может быть хорошим, но в настоящее время нет поддержки хрустальных шаров.;-) Попробуйте переопределить его своим собственным методом, возвращая 12345.
Некоторые наблюдения
Кажется, что obj.hashCode() является собственным вызовом, и объект может выйти. Изменение obj.hashCode() на obj.getMyCode() (метод, который возвращает System.currentTimeMillis()% staticObjCount) заставило его работать. Нет активности GC. Однако следующий метод так и не получил анализ побега со всеми упомянутыми предложениями.
Вот
public static long test1()
{
long r = 0;
byte[] arr = new byte[(int)System.currentTimeMillis() % 1024];
if(arr.length == 998 ) {
++r;
}
return r;
}
Используемые параметры JVM -server -verbosegc -XX: CompileThreshold = 1
Test1 вызывается несколько раз. Та же самая история. Java выделяет память в куче, GC приходит и делает все медленно. был слишком взволнован этой функцией.