2012-06-02 12 views
6

Así que estaba perfilando mi aplicación con VisualVM.VisualVM socket.read

Aparece un punto de acceso sobre mi interacción con MySQL. Lo primero que pensé fue que el punto caliente indicaba que mi aplicación estaba esperando después del IO. Pero en el informe de perfiles, VisualVM tiene dos columnas "Tiempo" y "Tiempo (CPU)". Tal vez el término se usa de manera incorrecta, pero asumí que la columna de auto-tiempo (cpu) excluía el tiempo de IO. Después de más depuración, llegamos a la conclusión de que la suposición era incorrecta y mostraba el tiempo de IO porque el punto de acceso estaba en java.net.SocketInputStream.read() del controlador MySQL y otras cosas IO que no deberían costar ninguna CPU.

Entonces, mi pregunta es ¿por qué visualvm informa SocketInputStream.read() como hora de CPU?

Screnshot

+0

Quizás haya alguna espera ocupada, p. llamando 'disponible()' en el ciclo? –

+0

Lo siento, mi error. Fue en java.net.SocketInputStream.read() – plcstpierre

Respuesta

4

las llamadas nativas siempre están en el estado RUNNABLE mientras se monitorea la actividad del subproceso, probablemente porque la JVM no tiene manera de saber si la llamada nativa está inactiva o si realmente está haciendo algo. Por lo tanto, el tiempo pasado en estado RUNNABLE cuenta como tiempo de CPU.

+1

¡Gracias! Eso es exactamente lo que estaba buscando. – plcstpierre

0

SocketInputStream.read() se bloquea hasta que haya datos disponibles desde el otro lado. Entonces podría ser una respuesta lenta de su base de datos.

+0

Lo sé. Esa no es mi pregunta. Mi pregunta es por qué visual vm lo marca como uso de la CPU? – plcstpierre

1

This very long thread afirma que las pequeñas escrituras podrían estar causando el problema. Vale la pena leerlo, pero no sé qué podrías hacer al respecto. ¿Qué podrías hacer? Puede asegurarse de que no está utilizando un pequeño fetch size. Esto no le da pequeñas escrituras, pero pequeñas lecturas que conducen al mismo problema. Puede probar diferentes plataformas para el cliente o servidor. Hay un comentario en this bug que lee:

"Hemos visto enormemente comportamiento diferente de la rapidez de E/S buffers se llenan entre Solaris y Linux (y por lo tanto el número de llamadas a ReadAheadInputStream.fill(), porque lee lo que está disponible, no se bloquea a menos que necesite leer más de lo que está disponible).

+0

Gracias, eso fue perspicaz, pero no fue la respuesta que estaba buscando :( – plcstpierre

Cuestiones relacionadas