Borrador de JEP: Deprecar los métodos de acceso a memoria en sun.misc.unsafe para su eliminación

El plan de Java para deprecar los métodos de acceso a memoria de bajo nivel de `sun.misc.Unsafe` en favor de APIs estándar más seguras como `VarHandle` y `MemorySegment` está reavivando tensiones de larga data entre rendimiento y seguridad en la JVM. Muchos aplauden garantías más fuertes y límites más claros alrededor del comportamiento inseguro, pero otros advierten que las comprobaciones de límites obligatorias y la pérdida de acceso de “coste cero” podrían perjudicar cargas de trabajo de alto rendimiento como compresión, cifrado, bases de datos y sistemas de trading, empujándolos potencialmente hacia código nativo u otros lenguajes. La propuesta depende de si las nuevas APIs y los flags opcionales pueden preservar un rendimiento cercano al de `Unsafe` mientras limpian la dependencia de la plataforma en internals no documentados.

Contexto de la JEP

  • La JEP propone deprecar y, con el tiempo, eliminar los métodos de acceso a memoria de sun.misc.Unsafe, en favor de:
    • VarHandle para memoria en heap.
    • MemorySegment (Foreign Function & Memory API) para memoria fuera del heap.
  • Se presentan como seguros, eficientes, estables y mejor integrados con las herramientas.
  • La deprecación implica un plazo largo; la eliminación está prevista solo después de varias versiones LTS.

Rendimiento y comprobación de límites

  • La controversia central: VarHandle/MemorySegment siempre realizan comprobaciones de límites, mientras que Unsafe puede evitarlas.
  • Varios participantes argumentan que las comprobaciones de límites pueden costar más del 10% y, a veces, mucho más en bucles cerrados, especialmente en:
    • Compresión/cifrado.
    • Cargas de trabajo con mucho parsing (por ejemplo, One Billion Row Challenge).
    • Estructuras de datos de bajo nivel y sistemas parecidos a HFT.
  • Otros responden que:
    • Los JIT modernos a menudo eliminan las comprobaciones de límites.
    • Unsafe puede inhibir otras optimizaciones y a veces rinde peor.
  • La capacidad del JIT para elidir comprobaciones para MemorySegment está limitada y requiere patrones no obvios; algunos lo consideran frágil.

Seguridad, comportamiento indefinido e integridad

  • Argumentos a favor de la eliminación:
    • Unsafe introduce comportamiento indefinido, fallos y problemas de seguridad.
    • La plataforma quiere integridad: el runtime y la aplicación deben saber dónde pueden violarse los invariantes.
    • Se alinea con la tendencia del sector a alejarse del comportamiento indefinido sin comprobaciones.
  • Los críticos dicen:
    • Los usuarios avanzados intercambian conscientemente seguridad por velocidad.
    • Tratar esto como una ideología ignora necesidades reales de rendimiento.

Alternativas y soluciones provisionales

  • Las APIs internas de jdk.internal seguirán siendo accesibles mediante flags de línea de comandos (--add-exports), visto como un “punto intermedio”.
  • Algunos proponen FFI nativo (JNI/Panama) como una vía de escape para el rendimiento; otros señalan el coste de llamadas y la complejidad.
  • Algunos proponen un modo explícito de “sin comprobación de límites” o un MemorySegment sin límites restringido, en lugar de una deprecación completa.

Preocupaciones del ecosistema y la migración

  • Preocupación por el impacto en grandes sistemas de datos Java (Kafka, Cassandra, Elasticsearch, HBase) que dependen de Unsafe.
  • Temor a que una paridad insuficiente:
    • Incentive quedarse en JDK antiguos (como ocurrió con 8/11 y los módulos).
    • Empuje a los usuarios sensibles al rendimiento hacia C++, Rust, Go o C#.
  • Otros sostienen que la mayoría de las bibliotecas pueden migrar con un impacto mínimo y que solo una pequeña fracción del código necesita realmente semántica al nivel de Unsafe.