12

有一些语言支持足够强大的类型系统,它们可以在编译时证明代码不会寻址超出其边界的数组。我的问题是,如果我们要将这样的语言编译到 JVM,是否有某种方法可以利用它来提高性能并删除每次数组访问时发生的数组边界检查?

1) 我知道最近的 JDK 支持一些数组绑定检查消除,但由于我在编译时知道某些调用是安全的,所以我可以更安全地删除。

2) 有些人可能认为这不会对性能产生太大影响,但它肯定会,尤其是在阵列/计算密集型应用程序中,例如科学计算。

关于铸造的同样问题。我知道某些东西是某种类型,但 Java 不是,因为它的类型系统有限。有没有办法告诉JVM“相信我”并跳过任何检查?

我意识到可能没有办法做到这一点,因为 JVM 通常是分布式的,用这个功能修改 JVM 是否合理?这是已经完成的事情吗?

这是将更强大的类型语言编译到 JVM 的挫折之一,它仍然受到 Java 限制的阻碍。

4

2 回答 2

3

原则上,如果没有携带证明代码(PCC) 基础设施,这不能以安全的方式完成。PCC 将允许您将您的安全推理嵌入class文件中。在类加载时检查您的嵌入式证明。如果证明中存在缺陷,则不会加载该类。

如果 JVM 允许您在不需要正式证明的情况下放弃运行时检查,那么,正如 SecurityMatt 所说,它将破坏 Java 作为安全平台的原始理念。

JVM 使用一种特殊形式的 PCC 对方法中的局部变量进行类型检查。类加载机制使用所有局部变量类型信息来检查其正确性,但在此之后被丢弃。但这是 JVM 中使用的 PCC 概念的唯一实例。据我所知,JVM 没有通用的 PCC 基础设施。

我曾经听说有一个支持 Java 小子集的 JavaCard 平台。不过,我不确定这是否有助于解决您的问题。

于 2012-11-27T19:37:06.180 回答
2

Java 的关键特性之一是它不需要“信任”开发人员来进行边界检查。这消除了可能导致攻击者能够在您的应用程序中执行任意代码的“缓冲区溢出”安全漏洞。

通过允许开发人员关闭边界检查的能力,Java 将失去其关键特性之一——无论 Java 开发人员有多么错误,他/她的代码中都不会出现任何可利用的缓冲区溢出。

如果您想使用一种信任程序员来管理他们自己的边界检查的语言,我建议您使用 C++。这使您能够分配没有自动边界检查的数组(new int[])和分配具有内置边界检查的数组(std::vector)。

此外,我强烈建议在将应用程序中的速度损失归咎于边界检查之前,执行一些基准测试以确定代码中是否存在可能导致瓶颈的其他地方。

您可能会发现,对于编译器目标,MSIL 等字节码语言比 Java 字节码更适合您的需求。MSIL 是强类型的,并且不会受到您在 Java 中发现的许多低效率的影响。

于 2012-11-27T17:33:50.063 回答