Подтвердить что ты не робот

Java PrintCompilation output: что означают "сделанные не абитуриенты" и "сделанные зомби",

При запуске приложения Java 1.6 (1.6.0_03-b05) я добавил флаг -XX:+PrintCompilation. На выходе для некоторых методов, в частности, некоторые из тех, которые, как мне известно, получаются много, я вижу текст made not entrant и made zombie.

Что это значит? Лучше всего предположить, что это шаг декомпиляции, прежде чем перекомпилировать этот метод или зависимость с большей оптимизацией. Это правда? Почему "зомби" и "абитуриент"?

Пример: довольно немного времени между некоторыми из этих строк:

[... near the beginning]
42       jsr166y.LinkedTransferQueue::xfer (294 bytes)

[... much later]
42    made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
---   n   sun.misc.Unsafe::compareAndSwapObject
170       jsr166y.LinkedTransferQueue::xfer (294 bytes)
170   made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
  4%      jsr166y.LinkedTransferQueue::xfer @ 29 (294 bytes)
171       jsr166y.LinkedTransferQueue::xfer (294 bytes)

[... even later]
42    made zombie  jsr166y.LinkedTransferQueue::xfer (294 bytes)
170   made zombie  jsr166y.LinkedTransferQueue::xfer (294 bytes)
171   made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
172       jsr166y.LinkedTransferQueue::xfer (294 bytes)

[... no further logs]
4b9b3361

Ответ 1

Я собрал некоторую информацию об этом на моем блоге. Клифф Нажмите комментарий, который я нашел, говорит:

Зомби-методы - это методы, чей код был недопустим при загрузке классов. Как правило, серверный компилятор делает агрессивные вложения решений не конечных методов. До тех пор, пока встроенный метод никогда не будет переопределен, код будет правильным. Когда подкласс загружается и метод переопределяется, скомпилированный код прерывается для всех будущих вызовов. Код объявляется "не входящим" (нет будущих абонентов для разбитого кода), но иногда существующие абоненты могут продолжать использовать код. В случае вложения, это недостаточно хорошо; существующие стеки кадров вызывающих абонентов "деоптимизируются", когда они возвращаются к коду из вложенных вызовов (или просто если они выполняются в коде). Когда больше кадров стека не помещают ПК в сломанный код, он объявляет "зомби" - готов к удалению после того, как GC приблизится к нему.

Ответ 2

Это абсолютно не область экспертизы для меня, но мне было интересно, и так было немного копать.

Несколько ссылок, которые могут вам показаться интересными: OpenJDK: nmethod.cpp, OpenJDK:. nmethod.hpp

Выдержка из nmethod.hpp:

// Make the nmethod non entrant. The nmethod will continue to be
// alive.  It is used when an uncommon trap happens.  Returns true
// if this thread changed the state of the nmethod or false if
// another thread performed the transition.
bool  make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); }
//...

Как начальное место.

Ответ 3

Вот это Gist с невероятным количеством информации на PrintCompilation. В частности, он говорит:

Когда происходит деоптимизация, если принято решение о признании недействительным оскорбительного nmethod, оно сначала будет "сделанным не первым"; и затем, когда NMethodSweeper обнаруживает, что никаких активировок на стеках уже нет, он "сделан зомби";