可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm developing an application that generates and compiles classes at runtime. This will sometimes create huge amounts of generated code.
With one of our test cases, I'm getting an error from the JVM:
TestClass.java:83865: too many constants
Just this. I've seen other reports about a similar error, but on those cases the error message complains about the constant pool. But in this case it doesn't.
If this means that the limit on the JVM's constant pool was reached, what does it mean? I mean, what kind of constants are these in terms of Java code? Class methods? Fields? Literals? I have no static or final methods nor fields.
Can you give me some leads?
EDIT:
Splitting the code into multiple classes is already in schedule. Although it wasn't for this exact reason.
I' aware of the limits of the constant pool, my doubt was exactly what goes into into. The generated code doesn't have more that about 10000 methods+fields.
My doubt is if literals also go to the constant pool or not, since that's the only reason I see to raise this number up to 65K. It seems so.
回答1:
http://en.wikipedia.org/wiki/Java_class_file#The_constant_pool
The constant pool includes numbers, strings, method names, field names, class names, references to classes and methods...basically everything.
There can be at most 65536 of them.
回答2:
Section 5.1 of the JVM spec defines exactly what constitutes the constant pool (mostly references to classes/methods and literals).
回答3:
From: JVM Spec
you can see that the classfile.constant_pool_count
has a 'u2' type, which limits it to 65535 entries
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]; }
回答4:
I don't know if this is very relevant, but for array constants, EVERY field counts towards it. I'm not quite sure why (my guess is that you don't actually give a literal, and thus the runtime have to put in every value manually, hence needing them all to be constants), but it's like that, and that's the way it is.
I found that problem when I generated a large cache as an array literal. Since I didn't want to write out 1 000 000 constants by hand, I wrote a small program to write the program for me. I wanted to see how fast the program was when everything was cached from startup.
(The problem in question is 1.6.1 from "Programming Challenges" by Skiela and Revilla, ISBN 0-387-00163-8)
So you may have some array somewhere with literals. That is not counted as ONE constant. It's counted as array.length constants. Or array.length + 1 constants.