【发布时间】:2017-03-02 12:20:12
【问题描述】:
我们知道,Java 在每次访问数组元素时都会检查索引是否超出范围。但在某些情况下,例如 Scala 中的映射函数,编译器/库会自己处理索引,从而保证不会越界访问。
那么,出于性能原因,是否可以在 JVM 中对代码的某些部分禁用此类边界检查?
【问题讨论】:
-
边界检查很少是实际的性能瓶颈,因为它被高度优化(至少循环提升)。如果您已完成指令级分析以确认确实如此,那么您可以考虑使用
Unsafe绕过检查。但据我所知,没有一个 JDK 类会做这样的事情,只有少数 3rd-party 高性能库可能。 -
@the8472 JDK 确实经常使用 Unsafe,例如hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/… 本来打算只用的,后来第三方库也查了 Unsafe。
-
@Kan CHM 使用 unsafe 进行并发(对字段的原子访问),我们正在讨论使用 unsafe 绕过数组中的边界检查
-
@the8472 无论如何,请参见 ArraySupport 类,它被
java.util.Arraysgithub.com/netroby/jdk9-dev/blob/master/jdk/src/java.base/share/… 使用,也 nioXxxBuffer非常依赖 Unsafe。公共 API 只是将 Unsafe 方法与额外的检查一起包装以使其安全。 -
@kan 他们使用 unsafe 来访问堆外数据,您总是必须手动进行偏移计算。本次讨论是关于通过 Unsafe 访问 java 数组(即堆上)并且根本不进行任何边界检查以消除进行边界检查的微小成本。通常编译器无论如何都非常擅长将那些提升出循环,这就是为什么很少有需要这种优化的情况,我认为你不会在 JDK 中找到。
标签: java arrays scala memory-management jvm