标准答案
- 新对象的分配会受到线程本地分配缓冲区、对象大小、堆空间和 GC 实现影响。
- 未逃逸对象不会被外部线程或方法观察,JIT 可能消除对象分配或拆成字段。
- 逃逸分析可能因反射、虚调用、调试或复杂控制流失效,不能依赖它替代合理的对象和缓存设计。
- 判断分配问题要结合分配速率、堆转储、GC 日志和性能剖析。
题目解析
对象分配受到 TLAB、对象大小、堆状态和垃圾收集器影响;短命小对象可能在本地分配缓冲区快速创建。分配快不等于对象生命周期短,真正的压力还取决于分配速率和存活对象。
逃逸分析由 JIT 根据运行时信息判断对象是否离开方法或线程作用域,可能进行标量替换等优化。它是实现细节,不能作为代码层面的内存契约,也不能保证所有 new 都被消除。
排查分配问题要结合 allocation profile、GC 日志、堆转储和对象存活时间。只减少 new 次数可能牺牲可读性,却没有减少长生命周期缓存或队列。
常见误区
- 误区:每个 new 都一定触发慢速堆分配。改正:考虑 TLAB、JIT 和对象大小,但仍用真实 profile 验证分配成本。
- 误区:把逃逸分析当作开发者可以直接控制的 API。改正:通过代码结构和基准影响优化机会,但不能依赖它保证内存位置。
- 误区:只看对象数量不看存活时间。改正:同时看分配速率、晋升、存活对象和引用链,区分短命垃圾与泄漏。