2010-05-28 16 views
35

Cuando ejecuto una aplicación Java 1.6 (1.6.0_03-b05) agregué el -XX:+PrintCompilation. En el resultado de algunos métodos, en particular algunos de los que conozco se llaman mucho, veo el texto made not entrant y made zombie.java PrintCompilation output: cuál es el significado de "made not entrant" y "made zombie"

¿Qué significa esto? La mejor suposición es que es un paso de descompilación antes de volver a compilar ese método o una dependencia con una mayor optimización. ¿Es eso cierto? ¿Por qué "zombie" y "entrante"?

ejemplo, con un poco de tiempo entre algunas de estas líneas:

[... 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] 

Respuesta

22

He reunido algo de información sobre esto en my blog. Un comentario de Cliff Click que encontré dice:

Los métodos de Zombie son un código cuyo código ha sido invalidado por la carga de clases. En general, el compilador del servidor toma decisiones agresivas sobre métodos no finales. Siempre que el método en línea nunca se anule, el código es correcto. Cuando se carga una subclase y se anula el método, el código compilado se interrumpe para todas las futuras llamadas a él. El código se declara "no entrante" (no hay personas que llaman en el futuro al código roto), pero a veces las personas que llaman pueden seguir usando el código. En el caso de inline, eso no es lo suficientemente bueno; Las tramas de pila de las personas que llaman se "desoptimizan" cuando vuelven al código de las llamadas anidadas (o solo si se están ejecutando en el código). Cuando ya no haya más monturas de monturas que sujeten las PC al código roto, se declarará como "zombie", listo para ser retirado una vez que el GC lo haya solucionado.

+7

Kris Mok escribió una respuesta a JodaStephen, que ahora está vinculada desde su blog y es aún más completa en su descripción de -XX: + PrintCompilation; aquí está el enlace: https://gist.github.com/1165804#file_notes.md – Blaisorblade

9

Esto no es absolutamente un área de especialización para mí, pero yo estaba interesado y también lo hizo un poco de excavación.

Un par de enlaces que pueden interesarle: OpenJDK:nmethod.cpp, OpenJDK:nmethod.hpp.

Un extracto de 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); } 
//... 

Así como un punto de partida.

+0

Ese es un comienzo útil, gracias. Cuanto más miro el código, ¡más vocabulario de punto de acceso encuentro que no sé! Entonces, ¿creemos que "not_entrant" simplemente significa "no ejecutar este código compilado de nuevo, necesita desvincular/recompilar primero"? Otro enlace: vea la línea 536 de http://www.google.com/codesearch/p?hl=en#aRIt9pqzOVI/src/share/vm/oops/methodOop.cpp –

+3

Dado el significado de "participante" mi * supongo * sería que marca el método compilado para no ser * ingresado * nuevamente (aunque algunos hilos todavía pueden estar en él) mientras que zombie significa que no tiene más uso y puede eliminarse. Al igual que un mostrador de caja podría anunciar que no aceptará nuevos clientes (no entrante), pero igual tendrá que atender a los clientes en cola antes de cerrar la caja (zombie). Pero es solo una suposición. –

+0

Buena analogía: p –

1

Here is a Gist con una cantidad increíble de información en PrintCompilation. En concreto, se dice:

Cuando deoptimization sucede, si se decide a invalidar el infractor nmethod, será "no hecho entrante" en primer lugar; y luego, cuando el NMethodSweeper descubre que ya no hay activaciones de él en las pilas, está "hecho zombie";

Cuestiones relacionadas