Ошибка Java «слишком много констант»

Я разрабатываю приложение, которое генерирует и компилирует классы во время выполнения. Это иногда создает огромное количество сгенерированного кода.

В одном из наших тестов я получаю сообщение об ошибке от JVM:

TestClass.java:83865: too many constants

Просто это. Я видел другие сообщения о подобной ошибке, но в этих случаях сообщение об ошибке жалуется на постоянный пул. Но в этом случае это не так.

Если это означает, что лимит на постоянный пул JVM достигнут, что это значит? Я имею в виду, что это за константы с точки зрения Java-кода? Классовые методы? Поля? Литералы? У меня нет ни статических, ни финальных методов, ни полей.

Можете ли вы дать мне некоторые выводы?

РЕДАКТИРОВАТЬ:

Разделение кода на несколько классов уже запланировано. Хотя это было не по этой точной причине.

Я & APOS; зная об ограничениях постоянного пула, мои сомнения были именно в том, что входит в. Сгенерированный код не имеет более 10000 методов + полей.

Я сомневаюсь, что литералы также идут в постоянный пул или нет, так как это единственная причина, по которой я вижу, поднять это число до 65K. Кажется так.

 Francisco Spaeth11 июл. 2012 г., 19:16
что это за код?
 Louis Wasserman11 июл. 2012 г., 19:35
Наименования методов и др.StringДоступно через отражение, перейдите в постоянный пул.
 Hot Licks11 июл. 2012 г., 19:18
Предположительно это означает, что какой-то предел был достигнут. Я забыл, каковы ограничения константного пула, но есть и другие ограничения внутри компилятора, которые также могут быть ответственными.
 Jon Taylor11 июл. 2012 г., 19:17
Вы можете найти эту ссылку полезной для чтенияmarxsoftware.blogspot.co.uk/2010/01/…
 Matt11 июл. 2012 г., 19:20
возможно, тот факт, что ваш код содержит 83K + строк в одном файле, может дать вам подсказку разбить его на несколько классов.

Ответы на вопрос(4)

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];
}

Раздел 5.1 спецификации JVM точно определяет, что составляет пул констант (в основном ссылки на классы / методы и литералы).

насколько это актуально, но для констант массива КАЖДЫЕ поля имеют значение. Я не совсем уверен, почему (я предполагаю, что вы на самом деле не даете литерал, и, таким образом, среда выполнения должна вводить каждое значение вручную, следовательно, все они должны быть константами), но это так, и так оно и есть.

Я обнаружил эту проблему, когда сгенерировал большой кэш в виде литерала массива. Поскольку я не хотел выписывать 1 000 000 констант вручную, я написал небольшую программу, чтобы написать программу для меня. Я хотел посмотреть, как быстро работает программа, когда все кэшируется при запуске.

(Рассматриваемая проблема - 1.6.1 из «Сложности программирования», автор Skiela and Revilla, ISBN 0-387-00163-8)

Таким образом, у вас может быть какой-то массив с литералами. Это не считается одной константой. Он считается как константа длины массива. Или массив.длина + 1 константа.

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

Постоянный пул включает в себя числа, строки, имена методов, имена полей, имена классов, ссылки на классы и методы ... в основном все.

Их может быть не более 65536.

 halfwarp11 июл. 2012 г., 21:24
Таким образом, это означает, что речь идет не о количестве полей, которые я объявил в своем основном классе. Даже если эти поля объявлены в других классах, пока я ссылаюсь на них из того же основного класса, у меня будет та же проблема, верно?
 11 июл. 2012 г., 21:32
Количество различных полей, методов и т. Д., На которые ссылается какой-либо один класс, ограничено 65536, да, я так считаю.
 16 июл. 2012 г., 10:36
Луи прав - общее количество всех ссылок и определений, констант и т. Д. Ограничено этим числом. Таким образом, вы даже не можете подделать его, используя массивы и константы для индексации, так как индексы # также занимают слоты CP.

Ваш ответ на вопрос