Java 7和8中方法的最大大小


80

我知道Java的方法不能大于64 KB。这种限制导致我们从JavaCC语法生成的代码出现问题。我们在使用Java 6时遇到了问题,并且能够通过更改语法来解决此问题。是否已针对Java 7更改了限制,或者已针对Java 8计划了限制?

为了清楚起见。我不需要一个大于64 KB的方法。但是我写了一个可以编译成很大方法的语法。


4
当我尝试编译巨大的Braink代码时,我遇到了同样的问题。
johnchen902

3
鉴于没有相反的信息,我认为可以安全地假设此限制仍将在Java 8中强制执行。当然,另一个(昂贵的)选择可能是更改parboiled的语法引擎,这使您可以用纯Java编写语法。
fge13年

4
看一下这篇文章
Anirudha 2013年

7
我个人认为创建这么大的方法是JavaCC中错误。它确实应该能够传播其代码。特别是考虑到JVM绝对不是为优化如此庞大的方法而构建的。
Joachim Sauer

Answers:


58

根据JVMS7

end_pc是排他性的事实是Java虚拟机设计中的一个历史错误:如果某个方法的Java虚拟机代码正好是65535字节长,并且以一条1字节长的指令结尾,那么该指令就不能受到保护。由异常处理程序。编译器编写者可以通过将任何方法,实例初始化方法或静态初始化程序(任何代码数组的大小)的已生成Java虚拟机代码的最大大小限制为65534字节来解决此错误。

但这是关于Java 7Java 8没有最终规格,因此没有人(除其开发人员以外)可以回答这个问题。

UPD(2015-04-06)根据JVM8,它也适用Java 8


2
确实在Java中存在这样的“错误”,但仍未解决?可能是一个沉重的限制,尤其是对于LaurentG情况。
Francesco Belladonna

3
@ Fire-Dragon-DoL引用的讨论仅是关于该方法的长度必须比其他方法少一个字节。这是非常无关紧要的。限制不是由于这样的简单“错误”引起的:它在字节码的总体设计中,要对其进行修复,需要重新指定整个字节
Marko Topolnik

11

好问题。与往常一样,我们应该从源头中找到答案(“Java®虚拟机规范”)。该部分虽然没有明确提及限制(就像Java6 VM规范一样),但在某种程度上是出于谨慎的考虑:

调用方法(第2.6节)时创建的框架的局部变量数组中的最大局部变量数受Code属性(第4.7.3节)的max_locals项的大小(限制为65535)的限制,从而提供了方法的代码。方法,并通过Java虚拟机指令集的16位局部变量索引。

干杯,


5
OP要求“最大数量的局部变量”具有相同的数值,但仍然与“一种方法的最大尺寸”完全不同。
Holger

8

它没有改变。在Java 7和Java 8中,方法中的代码限制仍然是64 KB。

参考文献:

  1. 根据Java 7虚拟机规范(4.9.1静态约束):

类文件中Java虚拟机代码的静态约束指定了Java虚拟机指令必须在代码数组中的布局方式以及各个指令的操作数必须是什么。

对代码数组中指令的静态约束如下:

  • 代码数组不能为空,因此code_length项的值不能为0。
  • code_length项的值必须小于65536。
  1. 根据Java 8虚拟机规范(4.7.3代码属性):

code_length项的值给出此方法在代码数组中的字节数。

code_length的值必须大于零(因为代码数组不能为空)且小于65536。


1

Andremoniy已经回答了java 7这个问题的一部分,但是当时似乎是要做出决定了,java 8所以我完成了涵盖该部分的答案:

jvms报价:

end_pc是互斥的事实是Java虚拟机设计中的一个历史错误:如果某个方法的Java虚拟机代码正好是65535字节长,并且以一条1字节长的指令结尾,那么该指令将无法得到保护。由异常处理程序。编译器编写者可以通过将任何方法,实例初始化方法或静态初始化程序(任何代码数组的大小)的已生成Java虚拟机代码的最大大小限制为65534字节来解决此错误。

如您所见,这个历史问题似乎至少在此版本(java 8)中无法解决。


-1

作为一种解决方法,如果您可以访问解析器的代码,则可以对其进行修改,以使其在JVM编译器施加的任何限制内工作……(假设无需花费太多时间在解析器代码中查找到修改)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.