1 puntos por GN⁺ 2024-11-12 | 1 comentarios | Compartir por WhatsApp
  • 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, #29 y #30

1 comentarios

 
GN⁺ 2024-11-12
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 final que originalmente deberían ser inmutables, el código de usuario se está perdiendo optimizaciones importantes que solo son posibles para clases provistas por el sistema
    La plataforma, en especial el compilador y el runtime, debe hacer cumplir restricciones semánticas de forma muy estricta para preservar margen para optimizaciones futuras

    • Estamos cambiando esta parte como parte de nuestra estrategia de integrity by default [1], y pronto saldrá un JEP relacionado
      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ícitamente open, así que en adelante la idea es que la aplicación tenga que otorgar permisos al módulo que quiera cambiar final
      Es parecido a lo que aplicamos recientemente a llamadas nativas y acceso inseguro a memoria
      [1]: https://openjdk.org/jeps/8305968
    • Da la impresión de que parte del pecado original vino de quienes siguieron Effective Java a ciegas con la idea de ponerle final a todo
      Por eso ahora no se pueden mockear fácilmente clases final en pruebas, y las herramientas de mocking tienen que llegar incluso a la manipulación de bytecode para poder hacerlo
      Por 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 mockear
    • El caso de System.out es un problema de la propia Java
      https://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
    • Los modificadores de campo no son una restricción de seguridad, sino una restricción semántica
      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
    • Admito que una vez escribí personalmente un malicioso código de tres líneas para “des-finalizar” un miembro, cambiarlo y luego volver a dejarlo como final, todo para evitar un refactor incómodo en una librería interna desaparecida hace mucho
      Ojalá 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

    • Si se le puede llamar “moderno”, el enfoque multiplataforma actual es interesante
      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’?

    • Parece que le cambiaron el nombre cuando empezaron a conocerse por primera vez detalles sobre el comportamiento en línea de Justin Rolland
  • 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

    • Supongo que no soy el único, pero probablemente es que no necesito Java
      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
    • Sumando a las otras respuestas, Java también tiene suficientes características útiles para una startup como para que tenga sentido usarlo en un proyecto nuevo
      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
    • Encima de la JVM hay muchos lenguajes muy cómodos de usar, como Clojure
      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.
    • Si voy a responder de forma incendiaria a un comentario incendiario: Java es mejor que Go en todos los sentidos, y para casi todos los casos que mencionaste, un 90% se puede resolver con Java
      Así que, para casi cualquier cosa, Java es una opción bastante claramente buena
    • Puede que no seas el único, pero tampoco todo el mundo piensa así
      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