11

実行時にクラスを生成してコンパイルするアプリケーションを開発しています。これにより、大量のコードが生成されることがあります。

テスト ケースの 1 つで、JVM からエラーが発生しました。

TestClass.java:83865: too many constants

これだけ。同様のエラーに関する他のレポートを見たことがありますが、それらの場合、定数プールに関するエラー メッセージが表示されます。しかし、この場合はそうではありません。

これが JVM の定数プールの制限に達したことを意味する場合、それはどういう意味ですか? つまり、Java コードに関して、これらはどのような定数なのでしょうか? クラスメソッド?田畑?リテラル?静的または最終的なメソッドもフィールドもありません。

手がかりを教えてもらえますか?

編集:

コードを複数のクラスに分割することは、すでに予定されています。この正確な理由ではありませんでしたが。

私はコンスタントプールの限界を認識しており、私の疑問はまさに何が入るかでした。生成されたコードには、約 10000 のメソッドとフィールドしかありません。

リテラルも定数プールに移動するかどうかは疑問です。これが、この数値を 65K まで上げる唯一の理由だからです。そのようです。

4

4 に答える 4

10

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

定数プールには、数値、文字列、メソッド名、フィールド名、クラス名、クラスおよびメソッドへの参照...基本的にすべてが含まれます。

それらは最大で 65536 個存在する可能性があります。

于 2012-07-11T17:18:35.227 に答える
2

JVM仕様のセクション5.1は、定数プールを構成するものを正確に定義しています(ほとんどの場合、クラス/メソッドおよびリテラルへの参照)。

于 2012-07-11T17:20:12.540 に答える
2

これが非常に関連性があるかどうかはわかりませんが、配列定数の場合、すべてのフィールドがカウントされます。理由はよくわかりません(私の推測では、実際にはリテラルを指定していないため、ランタイムはすべての値を手動で入力する必要があるため、すべての値を定数にする必要があります)が、そのようなものであり、それがそのままです。

大きなキャッシュを配列リテラルとして生成したときに、その問題が見つかりました。1 000 000 個の定数を手で書きたくなかったので、プログラムを作成するための小さなプログラムを作成しました。起動からすべてがキャッシュされたときのプログラムの速度を確認したかったのです。

(問題の問題は、Skiela と Revilla による「Programming Challenges」、ISBN 0-387-00163-8 の 1.6.1 です)

したがって、リテラルを含む配列がどこかにある場合があります。これは 1 つの定数としてカウントされません。array.length 定数としてカウントされます。または array.length + 1 定数。

于 2016-11-06T16:44:44.400 に答える
2

出典: JVM 仕様

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];
}
于 2012-07-11T17:27:01.133 に答える