- Una serie continua de mini posts que descompone el conocimiento interno de la JVM en unidades pequeñas, donde cada texto se enfoca en un solo tema, prueba, benchmark u observación
- Cada post apunta a una lectura de 5 a 10 minutos y parte de la idea de que los componentes de la JVM interactúan entre sí
- La evidencia y la discusión pueden ser anecdóticas y puede que no hayan pasado por una revisión suficiente de errores, consistencia, estilo, gramática o duplicados, así que conviene ser cauteloso antes de confiar en ello tal cual
- La colección completa se ofrece en ePUB, MOBI y PDF; el PDF pesa varias decenas de MB debido a la conversión de alta calidad
- El índice de artículos individuales se divide en los ejes Compiler, Runtime, GC y Library, y cubre temas internos de la JVM como optimización de bloqueos, TLAB, pausas de GC,
String.intern(), safepoint, referencias comprimidas y movimientos condicionales
Premisas para leer la serie
- JVM Anatomy Quarks es una serie continua de mini posts que organiza conocimientos básicos de la JVM en textos breves
- Cada post profundiza en un solo tema, prueba, benchmark u observación
- Si se lee un solo post por separado, puede faltar contexto, y la mayoría de los elementos tratados interactúan fácilmente entre sí
- La evidencia y la discusión del texto pueden ser anecdóticas, y puede que no hayan sido revisadas lo suficiente en cuanto a errores, consistencia, estilo, gramática, significado o duplicación
- Al usar o confiar en el contenido, el lector debe asumir el riesgo por su cuenta
Archivos compilados y estructura del índice
- La colección completa de la serie se ofrece en tres formatos
- ePUB es el más pequeño, pesa menos de 1 MB y está basado en Pandoc HTML-to-ePUB
- MOBI es pequeño, de tamaño en MB, y está basado en KindleGen ePUB-to-MOBI
- PDF pesa varias decenas de MB, es muy grande, y ofrece una salida de alta calidad basada en wkhtmltopdf HTML-to-PDF
- Los índices individuales están organizados en las categorías Compiler, Runtime, GC y Library
Lista de artículos por tema
-
Elementos centrados en Compiler
#1: Lock Coarsening and Loops#14: Constant Variables#15: Just-In-Time Constants#16: Megamorphic Virtual Calls#17: Trust Non-Static Final Fields#18: Scalar Replacement#19: Lock Elision#20: FPU Spills#25: Implicit Null Checks#27: Compiler Blackholes#28: Frequency-Based Code Layout#29: Uncommon Traps#30: Conditional Moves
-
Elementos entre Runtime y GC
- Son textos que tratan el comportamiento de memoria y de pausas durante la ejecución de la JVM
#2: Transparent Huge Pages#4: TLAB Allocation#5: TLABs and Heap Parsability#6: New Object Stages#7: Object Initialization Costs#9: JNI Critical and GC Locker#22: Safepoint Polls
-
Elementos centrados en GC
- Se enfocan en el diseño del recolector y el comportamiento del heap
#3: GC Design and Pauses#11: Moving GC and Locality#13: Intergenerational Barriers#21: Heap Uncommit
-
Elementos centrados en Runtime
- Tratan el entorno de ejecución de la JVM y la representación de objetos
#12: Native Memory Tracking#23: Compressed References#24: Object Alignment#26: Identity Hash Code
-
Elementos de Library o de clasificación mixta
- Entre los elementos que incluyen Library está
#10: String.intern() - Entre los elementos marcados tanto como Compiler como Runtime están
#16,#25,#29y#30
- Entre los elementos que incluyen Library está
1 comentarios
Comentarios de Hacker News
https://shipilev.net/jvm/anatomy-quarks/17-trust-nonstatic-f... es un caso realmente lamentable
Como algunos frameworks han abusado de JNI y la reflexión para modificar campos
finalque originalmente deberían ser inmutables, el código de usuario se está perdiendo optimizaciones importantes que solo son posibles para clases provistas por el sistemaLa plataforma, en especial el compilador y el runtime, debe hacer cumplir restricciones semánticas de forma muy estricta para preservar margen para optimizaciones futuras
En realidad, no hay mucho código que necesite modificar
final, y aun ahora esa tarea está limitada a clases dentro de su propio módulo o clases explícitamenteopen, así que en adelante la idea es que la aplicación tenga que otorgar permisos al módulo que quiera cambiarfinalEs parecido a lo que aplicamos recientemente a llamadas nativas y acceso inseguro a memoria
[1]: https://openjdk.org/jeps/8305968
finala todoPor eso ahora no se pueden mockear fácilmente clases
finalen pruebas, y las herramientas de mocking tienen que llegar incluso a la manipulación de bytecode para poder hacerloPor ejemplo, dentro de Google Effective Java es un requisito, así que incluso la API pública de GDrive tiene clases
final, cuando justo las APIs externas son las que uno querría mockearSystem.outes un problema de la propia Javahttps://docs.oracle.com/javase/specs/jls/se7/html/jls-17.htm...
Con un precedente así, no sorprende que otros también pensaran que era una forma aceptable de proceder
Debería ser posible saltárselos si se siguen los procedimientos de escape adecuados
El punto clave es la seguridad, porque alterar algo que no debería poder modificarse puede provocar un SEGV, y esa es precisamente la preocupación que intentan cubrir los modificadores de acceso
final, todo para evitar un refactor incómodo en una librería interna desaparecida hace muchoOjalá hubiera estado bloqueado, pero había exigencias del negocio
Hablando de algo un poco distinto, Apple acaba de lanzar un nuevo puente Java para Swift y está bastante bueno
Soporta tanto JNI como Panama, y la semana pasada lo estaban porteando a Android
https://github.com/swiftlang/swift-java
Gracias a la interoperabilidad entre lenguajes, en los casos adecuados una sola librería puede compartirse entre varias plataformas
Hasta ahora esto se hacía solo con C++, añadiendo una API en C si hacía falta, pero cuando C++ en sí no es necesario, claramente no es el lenguaje preferido
Aun así, me preocupa el costo. Si en una app móvil Swift pudiera llamar fácilmente a una librería Kotlin, parecería que la app de iOS tendría que cargar de alguna forma algo parecido a una JVM, y al revés, si una app de Android llamara a Swift, probablemente terminaría cargando el runtime de Swift
Al final hay sobrecarga
Me preocupa que algún día se vuelva común que los desarrolladores dependan de una librería Swift, que esa librería dependa de una librería Kotlin y levante una JVM, y luego vuelva a llamar a C++ vía JNI
Se parece a lo que pasa con los gestores de paquetes modernos, donde aunque tengas pocas dependencias directas, por lo “fácil que es y porque nadie le presta atención”, el programa termina enseguida con más de 100 dependencias transitivas
Qué bueno que compartieran aquí esta buena colección de artículos. Aprendí mucho sobre la JVM viendo esta serie
En especial me gusta este artículo que explica que la expresión que suele llamarse “asignación en stack” en Java está mal usada: https://shipilev.net/jvm/anatomy-quarks/18-scalar-replacemen...
Lo que la JVM realmente hace es análisis de escape + reemplazo escalar
Me gusta la longitud de estos artículos
Está bueno poder leer uno completo en unos minutos y, si quieres, correr el benchmark localmente
Si has trabajado algunos años con lenguajes basados en la JVM, esta colección de artículos es realmente interesante
Todavía recuerdo cuando empecé a leerlos por primera vez hace unos años
¿Alguien sabe por qué el nombre de esta serie cambió desde ‘JVM Anatomy Park’?
Casi me he olvidado de Java
Ya no se me ocurre para nada empezar un proyecto nuevo en Java
Si necesito desarrollo rápido y flexibilidad, usaría Python; si quisiera manejar mucha concurrencia de entrada/salida con recolección de basura, Go; si necesitara un lenguaje compilado, bueno y equilibrado, Swift; y si quisiera un lenguaje compilado con rendimiento y seguridad, Rust
Es solo una preferencia personal, y sé que Kotlin ha hecho que Java sea más cómodo de usar, pero igual me sigue dando esa impresión
Las principales fortalezas de Java son que hay una cantidad casi infinita de desarrolladores con experiencia en Java, que su conjunto de bibliotecas existentes es enorme y una buena parte está orientada a empresa, que facilita gestionar bases de código muy grandes con muchos contribuidores, y que su VM estándar, desarrollada durante décadas, es muy sólida, bastante rápida y está soportada en prácticamente todas las plataformas
Ya no tiene el dominio aplastante que tenía a principios de los 2000, ni siquiera en entornos empresariales, y sí, es el típico lenguaje “blub”, pero si esperas una escala empresarial y te importa más escalar con muchos desarrolladores que el rendimiento puro, sigue siendo una opción totalmente razonable
Me gusta Rust, pero Java es lo que me da de comer
Con frameworks modernos y ayuda de IA, puedes levantar un backend decente en cuestión de días
Si eres un cofundador técnico en solitario, para sacar un MVP rápido basta con saber Java o Kotlin, además del stack de frontend, y en la práctica vas a dedicar mucho más tiempo a tareas fuera de programar, así que las diferencias de funciones del lenguaje importan menos
Si vas por móvil nativo, Swift puede ser tu segundo lenguaje
Además, es muy probable que la escalabilidad no sea el primer problema por un buen tiempo. Lo más probable es que antes llegue el crecimiento del equipo, y los cuellos de botella de rendimiento se noten mucho después
Java encaja bien con equipos grandes
Desde una perspectiva de negocio, si quieres un pool de talento más grande, ciclos de entrega rápidos y algo que pueda seguir siendo tu stack principal a largo plazo, Java o Kotlin probablemente sean la mejor opción
Si quieres usar una tecnología llamativa como una especie de beneficio para atraer cierto tipo de desarrolladores, o si tienes un caso de negocio poco común, podrías elegir Go o Rust
Python es popular en la academia y en los bootcamps, pero sinceramente no tengo muy claro su valor de negocio para un backend de propósito general
Yo no ignoraría a toda la JVM. La JVM es una obra maestra de ingeniería y hoy está evolucionando rápido. Basta con ver Loom, Panama, Leyden, etc.
Así que, para casi cualquier cosa, Java es una opción bastante claramente buena
Kotlin junto con Java 21+ es mi combinación preferida para servicios centrados en E/S o, en realidad, casi cualquier tipo de servicio
Es realmente cómodo de usar y, gracias a los hilos virtuales, permite escribir código tan simple y eficiente como en Go, mientras aprovechas un ecosistema de bibliotecas que está entre los más grandes y mejores del mundo
No intento menospreciar a Go ni a Python. Si son tus herramientas preferidas, están perfectamente bien
Solo que Java no se ha vuelto tan irrelevante como algunos creen