我正在尝试帮助正在获取ClassFormatError的客户端。错误消息显示
bytecode array size > 65535 at offset=66370
堆栈跟踪指示尝试在实用程序类中调用静态方法时发生错误。我无法在自己的系统上重现错误。
我尝试了谷歌搜索问题(search = classformaterror“字节码数组大小”,包含引号)并找到了其他软件的错误报告,但没有任何帮助。我也尝试在这里搜索,但找不到涉及此特定错误消息的结果。 (也许我只是找不到它们......)
知道可能导致此问题的原因是什么?我无法发布代码或实际的堆栈跟踪,因为它是专有的。
提前感谢任何指针,你可以告诉我在哪里看。
答案 0 :(得分:4)
进一步阐述Jon Skeet的回应:
类文件格式为每个方法的字节码数组指定一个4字节长度的字段,但实际上某些构造(局部变量表,行号表和例外表)将此限制为65535。
前两个是可选的,如果编译没有调试信息的类,则不编译,但第三个是必需的。当然,如果在方法的后半部分没有异常处理,编译器可能不会注意到它。或者更糟糕的是,它可能溢出并编译一个损坏的try-catch块。
无论哪种方式,实用程序类中的一个或多个方法太大,即使没有硬编码长度限制,也可能应该拆分。
更新:当然在代码验证程序的描述中,代码长度显式上限为65536字节。但不可避免地会有一些实施方案将其作为指导方针。 :)
答案 1 :(得分:2)
这表明实用类方法基本上太大了,需要拆分。不同的编译器会输出不同数量的代码 - 我想不同的VM也可能或多或少地严格执行约束。
此外,您可能会发现在没有调试信息的情况下编译实用程序类会使方法处于限制之下 - 但最好将其拆分。
答案 2 :(得分:1)
我想从Java VM规范 - Java SE 7 Edition(准确地说是第4.7.3段)中分享以下内容:
end_pc独占的事实是一个历史错误 Java虚拟机的设计:如果是Java虚拟机代码 对于一个方法,正好是65535字节长,并以一条指令结束 这是1个字节长,然后该指令不能被a保护 异常处理程序编译器编写者可以解决这个问题 限制生成的Java虚拟机代码的最大大小 对于任何方法,实例初始化方法或静态初始化程序 (任何代码数组的大小)为65534字节。
所以这似乎是一个编译器特定的功能。必须要说的是,生成如此庞大的代码块不应该是Java中的问题(给定一个理智的设计),但在使用自动生成的代码时可能会出现问题。