Help, My Java Object Vanished (and the GC Is Not at Fault)
6 months ago
- #JVM
- #Java
- #Debugging
- 作为HotSpot Java虚拟机开发者的作者,在测试与Project Valhalla相关的新功能时遇到了Java对象和类莫名消失的问题。
- Project Valhalla引入了值对象(通过字段区分的对象),支持堆扁平化和标量替换等优化。
- 该问题的根源在于为符合JEP 450(紧凑对象头)规范而对markWord格式的修改,这重组了对象头中的元数据位。
- 该缺陷表现为大规模间歇性测试失败,包括不应为null的对象变为null以及NoClassDefFoundErrors错误,主要发生在未启用紧凑对象头时使用C2 JIT编译器的情况下。
- 调试过程最终锁定问题源于Object::hashCode内部函数中的错误编译,由检查本地指针位而非元数据位的错误位掩码导致。
- 根本原因是内存对齐问题——当值对象位因本地内存对齐发生位移后,错误的位掩码才显现出来。
- 解决方案是修正位掩码使其仅检查锁定位,从而消除对象变null和类定义丢失的现象。
- 关键收获包括:调试方法论的重要性、提出正确问题的技巧,以及高效利用调试工具的能力。