Prefacio

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

Cuando O'Reilly me propuso por primera vez escribir un libro sobre el ajuste del rendimiento de Java, no estaba seguro. Rendimiento de Java, pensé, ¿no habíamos acabado con eso? Sí, sigo trabajando a diario para mejorar el rendimiento de las aplicaciones Java (y de otras), pero me gusta pensar que paso la mayor parte del tiempo ocupándome de las ineficiencias algorítmicas y de los cuellos de botella externos del sistema, más que en algo directamente relacionado con el ajuste de Java.

Un momento de reflexión me convenció de que (como siempre) me estaba engañando a mí mismo. Es cierto que el rendimiento del sistema de extremo a extremo ocupa mucho de mi tiempo, y que a veces me encuentro con código que utiliza un O ( n 2 ) cuando podría utilizar uno con un rendimiento O(logN). Aun así, resulta que todos los días pienso en el rendimiento de la recolección de basura (GC), o en el rendimiento del compilador de la JVM, o en cómo obtener el mejor rendimiento de las API de Java.

No se trata de minimizar el enorme progreso que se ha hecho en el rendimiento de Java y las JVM en los últimos 20 años o más. Cuando era evangelista de Java en Sun a finales de los 90, el único "punto de referencia" real disponible era CaffeineMark 2.0 de Pendragon software. Por diversas razones, el diseño de ese punto de referencia limitó rápidamente su valor; sin embargo, en su día, nos gustaba decir a todo el mundo que el rendimiento de Java 1.1.8 era ocho veces más rápido que el rendimiento de Java 1.0 basado en ese punto de referencia. Y era cierto: Java 1.1.8 tenía un compilador justo a tiempo, mientras que Java 1.0 era casi completamente interpretado.

Entonces, los comités de estándares empezaron a desarrollar puntos de referencia más rigurosos, y el rendimiento de Java empezó a centrarse en ellos. El resultado fue una mejora continua en todas las áreas de la JVM: recogida de basura, compilaciones y dentro de las API. Ese proceso continúa hoy en día, por supuesto, pero uno de los hechos interesantes sobre el trabajo de rendimiento es que se vuelve sucesivamente más difícil. Conseguir multiplicar por ocho el rendimiento introduciendo un compilador "justo a tiempo" fue una simple cuestión de ingeniería, y aunque el compilador sigue mejorando, no volveremos a ver una mejora así. Paralelizar el recolector de basura supuso una enorme mejora del rendimiento, pero los cambios más recientes han sido más incrementales.

Este es un proceso típico de las aplicaciones (y la propia JVM no es más que otra aplicación): al principio de un proyecto, es bastante fácil encontrar cambios arquitectónicos (o errores de código) que, cuando se abordan, producen enormes mejoras de rendimiento. En una aplicación madura, encontrar tales mejoras de rendimiento es raro.

Ese precepto estaba detrás de mi preocupación original de que, en gran medida, el mundo de la ingeniería podría haber acabado con el rendimiento de Java. Unas cuantas cosas me convencieron de que estaba equivocado. La primera es el número de preguntas que veo a diario sobre cómo funciona tal o cual aspecto de la JVM en determinadas circunstancias. Nuevos ingenieros llegan a Java todo el tiempo, y el comportamiento de la JVM sigue siendo lo suficientemente complejo en ciertas áreas como para que una guía sobre su funcionamiento siga siendo beneficiosa. La segunda es que los cambios ambientales en la informática parecen haber alterado las preocupaciones sobre rendimiento a las que se enfrentan los ingenieros hoy en día.

En los últimos años, la preocupación por el rendimiento se ha bifurcado. Por un lado, ahora son comunes las máquinas muy grandes capaces de ejecutar JVM con pilas muy grandes. La JVM se ha movido para hacer frente a estas preocupaciones con un nuevo recolector de basura (G1), que -como nueva tecnología- requiere un poco más de ajuste manual que los recolectores tradicionales. Al mismo tiempo, la computación en nube ha renovado la importancia de las pequeñas máquinas de una sola CPU: puedes ir a Oracle o Amazon o a una serie de otras empresas y alquilar a bajo precio una máquina de una sola CPU para ejecutar un pequeño servidor de aplicaciones. (En realidad, no obtienes una máquina de una sola CPU: obtienes una imagen de un SO virtual en una máquina muy grande, pero el SO virtual está limitado al uso de una sola CPU. Desde la perspectiva de Java, eso resulta ser lo mismo que una máquina de una sola CPU). En esos entornos, gestionar correctamente pequeñas cantidades de memoria resulta ser bastante importante.

La plataforma Java también sigue evolucionando. Cada nueva edición de Java proporciona nuevas funciones del lenguaje y nuevas API que mejoran la productividad de los desarrolladores, aunque no siempre el rendimiento de sus aplicaciones. Las buenas prácticas en el uso de estas funciones del lenguaje pueden ayudar a diferenciar entre una aplicación que brilla y otra que avanza lentamente. Y la evolución de la plataforma plantea interesantes cuestiones de rendimiento: no hay duda de que utilizar JSON para intercambiar información entre dos programas es mucho más sencillo que idear un protocolo propietario altamente optimizado. Ahorrar tiempo a los desarrolladores es una gran ganancia, pero el verdadero objetivo es asegurarse de que esa ganancia de productividad vaya acompañada de una ganancia de rendimiento (o, al menos, de un equilibrio).

Quién debería (y quién no) leer este libro

Este libro está pensado para ingenieros de rendimiento y desarrolladores que quieran comprender cómo afectan al rendimiento diversos aspectos de la JVM y las API de Java.

Si es domingo por la noche a última hora, tu sitio se va a poner en marcha el lunes por la mañana y buscas una solución rápida para los problemas de rendimiento, éste no es el libro para ti.

Si eres nuevo en el análisis del rendimiento y estás empezando ese análisis en Java, este libro puede ayudarte. Ciertamente, mi objetivo es proporcionar suficiente información y contexto para que los ingenieros noveles puedan entender cómo aplicar principios básicos de ajuste y rendimiento a una aplicación Java. Sin embargo, el análisis de sistemas es un campo muy amplio. Hay una serie de recursos excelentes para el análisis de sistemas en general (y esos principios, por supuesto, se aplican a Java), y en ese sentido, lo ideal es que este libro sea un compañero útil de esos textos.

A un nivel fundamental, sin embargo, hacer que Java vaya realmente rápido requiere un profundo conocimiento de cómo funcionan realmente la JVM (y las API de Java). Existen cientos de indicadores de ajuste de Java, y ajustar la JVM tiene que ser algo más que probarlos a ciegas y ver qué funciona. En lugar de eso, mi objetivo es proporcionar conocimientos detallados sobre lo que hacen la JVM y las API, con la esperanza de que si entiendes cómo funcionan esas cosas, podrás observar el comportamiento específico de una aplicación y comprender por qué funciona mal. Comprendiendo eso, se convierte en una tarea sencilla (o al menos más simple) deshacerse del comportamiento indeseable (que funciona mal).

Un aspecto interesante del trabajo de rendimiento en Java es que los desarrolladores suelen tener una formación muy diferente a la de los ingenieros de un grupo de rendimiento o control de calidad. Conozco a desarrolladores que pueden recordar miles de oscuras firmas de métodos en API de Java poco utilizadas, pero que no tienen ni idea de lo que significa la bandera -Xmn. Y conozco a ingenieros de pruebas que pueden obtener hasta el último gramo de rendimiento configurando varias banderas para el recolector de basura, pero que apenas pueden escribir un programa "Hola, mundo" adecuado en Java.

El rendimiento de Java cubre estas dos áreas: el ajuste de los indicadores del compilador y del recolector de basura, etc., y las buenas prácticas de uso de las API. Aunque tu interés principal no sean los aspectos de programación de Java, dedico bastante tiempo a hablar de programas, incluidos los programas de ejemplo utilizados para proporcionar muchos de los datos de los ejemplos.

Aun así, si tu interés principal es el rendimiento de la propia JVM -es decir, cómo alterar el comportamiento de la JVM sin codificar-, grandes secciones de este libro te seguirán resultando beneficiosas. Siéntete libre de saltarte las partes de codificación y centrarte en las áreas que te interesan. Y tal vez, por el camino, te hagas una idea de cómo las aplicaciones Java pueden afectar al rendimiento de la JVM y empieces a sugerir cambios a los desarrolladores para que te faciliten la vida en las pruebas de rendimiento.

Novedades de la segunda edición

Desde la primera edición, Java ha adoptado un ciclo de versiones de seis meses con versiones periódicas a largo plazo; eso significa que las versiones actuales compatibles que coinciden con la publicación son Java 8 y Java 11. Aunque la primera edición cubría Java 8, en aquel momento era bastante nuevo. Esta edición se centra en un Java 8 y un Java 11 mucho más maduros, con importantes actualizaciones del recolector de basura G1 y del Java Flight Recorder. También se presta atención a los cambios en la forma en que Java se comporta en entornos de contenedores.

Esta edición cubre las nuevas características de la plataforma Java, incluido un nuevo arnés de microcomprobación (jmh), nuevos compiladores just-in-time, compartición de datos de clases de aplicación y nuevas herramientas de rendimiento, así como la cobertura de las nuevas características de Java 11, como las cadenas compactas y la concatenación de cadenas.

Convenciones utilizadas en este libro

En este libro se utilizan las siguientes convenciones tipográficas:

Cursiva

Indica nuevos términos, URL, direcciones de correo electrónico, nombres de archivo y extensiones de archivo.

Constant width

Se utiliza en los listados de programas, así como dentro de los párrafos para referirse a elementos del programa como nombres de variables o funciones, bases de datos, tipos de datos, variables de entorno, sentencias y palabras clave.

Constant width bold

Muestra comandos u otros textos que deben ser tecleados literalmente por el usuario.

Constant width italic

Muestra el texto que debe sustituirse por valores proporcionados por el usuario o por valores determinados por el contexto.

Este elemento significa un resumen de los puntos principales.

Utilizar ejemplos de código

El material complementario (ejemplos de código, ejercicios, etc.) se puede descargar en https://github.com/ScottOaks/JavaPerformanceTuning.

Este libro está aquí para ayudarte a hacer tu trabajo. En general, si se ofrece código de ejemplo con este libro, puedes utilizarlo en tus programas y documentación. No es necesario que te pongas en contacto con nosotros para pedirnos permiso, a menos que estés reproduciendo una parte importante del código. Por ejemplo, escribir un programa que utilice varios trozos de código de este libro no requiere permiso. Vender o distribuir ejemplos de los libros de O'Reilly sí requiere permiso. Responder a una pregunta citando este libro y el código de ejemplo no requiere permiso. Incorporar una cantidad significativa de código de ejemplo de este libro en la documentación de tu producto sí requiere permiso.

Agradecemos, pero no exigimos, la atribución. Una atribución suele incluir el título, el autor, la editorial y el ISBN. Por ejemplo "Java Performance por Scott Oaks (O'Reilly). Copyright 2020 Scott Oaks, 978-1-492-05611-9".

Si crees que el uso que haces de los ejemplos de código no se ajusta al uso legítimo o al permiso concedido anteriormente, no dudes en ponerte en contacto con nosotros en http://oreilly.com.

Aprendizaje en línea O'Reilly

Durante más de 40 años, O'Reilly Media ha proporcionado formación tecnológica y empresarial, conocimientos y perspectivas para ayudar a las empresas a alcanzar el éxito.

Nuestra red única de expertos e innovadores comparten sus conocimientos y experiencia a través de libros, artículos, conferencias y nuestra plataforma de aprendizaje online. La plataforma de aprendizaje en línea de O'Reilly te ofrece acceso bajo demanda a cursos de formación en directo, rutas de aprendizaje en profundidad, entornos de codificación interactivos y una amplia colección de textos y vídeos de O'Reilly y de más de 200 editoriales. Para más información, visita http://oreilly.com.

Cómo contactar con nosotros

Dirige tus comentarios y preguntas sobre este libro a la editorial:

  • O'Reilly Media, Inc.
  • 1005 Gravenstein Highway Norte
  • Sebastopol, CA 95472
  • 800-998-9938 (en Estados Unidos o Canadá)
  • 707-829-0515 (internacional o local)
  • 707-829-0104 (fax)

Tenemos una página web para este libro, donde se enumeran erratas, ejemplos y cualquier información adicional. Puedes acceder a esta página en https://oreil.ly/java-performance-2e.

Envía un correo electrónico para comentar o hacer preguntas técnicas sobre este libro.

Para más información sobre nuestros libros, cursos, conferencias y noticias, consulta nuestro sitio web en http://www.oreilly.com.

Encuéntranos en Facebook: http://facebook.com/oreilly

Síguenos en Twitter: http://twitter.com/oreillymedia

Míranos en YouTube: http://www.youtube.com/oreillymedia

Agradecimientos

Me gustaría dar las gracias a todas las personas que me han ayudado mientras trabajaba en este libro. En muchos sentidos, este libro es una acumulación de conocimientos adquiridos a lo largo de mis últimos 20 años en el Grupo de Rendimiento de Java y otros grupos de ingeniería de Sun Microsystems y Oracle, por lo que la lista de personas que han hecho aportaciones positivas a este libro es bastante amplia. A todos los ingenieros con los que he trabajado durante ese tiempo, y en particular a los que han respondido pacientemente a mis preguntas aleatorias durante el último año, ¡gracias!

Me gustaría dar las gracias especialmente a Stanley Guan, Azeem Jiva, Kim LiChong, Deep Singh, Martijn Verburg y Edward Yue Shung Wong por el tiempo que dedicaron a revisar los borradores y por sus valiosos comentarios. Estoy seguro de que no pudieron encontrar todos mis errores, aunque el material que aquí se presenta ha mejorado mucho gracias a sus aportaciones. La segunda edición ha mejorado mucho gracias a la ayuda minuciosa y reflexiva de Ben Evans, Rod Hilton y Michael Hunger. Mis colegas Eric Caspole, Charlie Hunt y Robert Strout, del grupo de rendimiento de Oracle HotSpot, también me ayudaron pacientemente con diversas cuestiones de la segunda edición.

El personal de producción de O'Reilly fue, como siempre, muy servicial. Tuve el privilegio de trabajar con la editora Meg Blanchette en la primera edición, y Amelia Blevins guió la segunda de forma cuidadosa y atenta. Gracias por todos vuestros ánimos durante el proceso! Por último, debo dar las gracias a mi marido, James, por aguantar las largas noches y esas cenas de fin de semana en las que estaba en continuo estado de distracción.

Get Rendimiento de Java, 2ª Edición now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.