Java“太多常量”JVM错误

我正在开发一个在运行时生成和编译类的应用程序。 这有时会产生大量生成的代码。

在我们的一个测试用例中,我从JVM收到错误:

TestClass.java:83865: too many constants 

只是这个。 我已经看到有关类似错误的其他报告,但在这些情况下,错误消息抱怨常量池。 但在这种情况下它没有。

如果这意味着达到了JVM常量池的限制,那意味着什么? 我的意思是,就Java代码而言,这些常量是什么? class级方法? 场? 文字? 我没有静态或最终方法也没有字段。

你能给我一些线索吗?

编辑:

将代码拆分为多个类已经按计划进行。 虽然不是出于这个原因。

我意识到恒定池的限制,我的怀疑正是进入的原因。 生成的代码不超过10000个方法+字段。

我怀疑的是文字是否也会进入常数池,因为这是我看到将这个数字提高到65K的唯一原因。 看来是这样。

http://en.wikipedia.org/wiki/Java_class_file#The_constant_pool

常量池包括数字,字符串,方法名称,字段名称,类名,类和方法的引用……基本上所有内容。

最多可以有65536个。

JVM规范的5.1节确切地定义了常量池的构成(主要是对类/方法和文字的引用)。

来自: JVM Spec

你可以看到classfile.constant_pool_count有一个’u2’类型,它将它限制为65535个条目

 ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } 

我不知道这是否非常相关,但对于数组常量,每个字段都计入其中。 我不太清楚为什么(我的猜测是你实际上没有给出一个文字,因此运行时必须手动输入每个值,因此需要它们都是常量),但它就像那样,那就是它的方式。

当我将大缓存生成为数组文字时,我发现了这个问题。 由于我不想手工写出1 000 000个常数,我写了一个小程序来为我编写程序。 我想看一下从启动时缓存所有内容时程序的速度有多快。

(问题是来自Skiela和Revilla的“编程挑战”的1.6.1,国际标准书号0-387-00163-8)

所以你可能在文字的某个地方有一些数组。 这不算作一个常数。 它被算作array.length常量。 或者array.length + 1个常量。