Максимальный размер метода в Java 7 и 8

Я знаю, что метод не может быть больше 64 КБ с Java. Ограничение вызывает проблемы с генерируемым кодом из грамматики JavaCC. У нас были проблемы с Java 6 и они смогли исправить это, изменив грамматику. Был ли предел изменен для Java 7 или он запланирован для Java 8?

Просто, чтобы было ясно. Мне не нужен метод размером больше 64 КБ. Но я написал грамматику, которая компилируется в очень большой метод.

Ответ 1

Согласно JVMS7:

Тот факт, что end_pc является исключительным, является исторической ошибкой в дизайн виртуальной машины Java: если код виртуальной машины Java для метода составляет ровно 65535 байтов и заканчивается инструкцией то есть 1 байт в длину, тогда эта инструкция не может быть защищена обработчик исключений. Писатель-компилятор может обойти эту ошибку ограничение максимального размера сгенерированного кода виртуальной машины Java для любого метода, метода инициализации экземпляра или статического инициализатора (размер любого массива кода) до 65534 байта.

Но это примерно Java 7. Нет никаких окончательных спецификаций для Java 8, поэтому никто (кроме его разработчиков) не смог ответить на этот вопрос.

UPD (2015-04-06) В соответствии с JVM8 это также верно для Java 8.

Ответ 2

Хороший вопрос. Как всегда, мы должны пойти в источник, чтобы найти ответ (Спецификация виртуальной машины Java® ), В разделе явно не упоминается ограничение (как и спецификация VM Java Java), но несколько осмотрительно:

Наибольшее количество локальных переменных в массиве локальных переменных фрейма, созданного при вызове метода (§2.6), ограничено размером 65535 размером элемента max_locals атрибута Code (§4.7.3), что дает код метода и 16-битную локальную переменную индексации набора инструкций виртуальной машины Java.

Приветствия,

Ответ 3

Он не изменился. Предел кода в методах по-прежнему составляет 64 КБ как в Java 7, так и в Java 8.

Литература:

Статические ограничения кода Java Virtual Machine в файле класса определяют, как Инструкции Java Virtual Machine должны быть изложены в массиве кода и операнды отдельных инструкций должны быть.

Статические ограничения для команд в массиве кода следующие:

  • Массив кода не должен быть пустым, поэтому элемент code_length не может иметь значение 0.
  • Значение элемента code_length должно быть меньше 65536.
  1. Из спецификации виртуальной машины Java 8 (4.7.3 Атрибут кода):

Значение элемента code_length указывает количество байтов в массиве кода для этого метода.

Значение code_length должно быть больше нуля (поскольку массив кода должен не пусто) и менее 65536.

Ответ 4

Андромоний уже ответил на часть вопроса java 7, но, похоже, в то время вскоре было принято решение о java 8, поэтому я завершу ответ, чтобы покрыть эту часть:

Цитата из jvms:

Тот факт, что end_pc является исключительным, является исторической ошибкой в ​​дизайне виртуальной машины Java: если код Java Virtual Machine для метода составляет ровно 65535 байт и заканчивается инструкцией длиной 1 байт, то эта инструкция не может быть защищен обработчиком исключений. Писатель компилятора может обойти эту ошибку, ограничив максимальный размер сгенерированного кода виртуальной машины Java для любого метода, метода инициализации экземпляра или статического инициализатора (размер любого массива кода) до 65534 байта.

Как вы видите, эта историческая проблема, похоже, не исправляет, по крайней мере, в этой версии (java 8).

Ответ 5

Как обходной путь, и если у вас есть доступ к коду парсера, вы можете его изменить, чтобы работать в пределах любых ограничений, налагаемых компилятором JVM... (Предполагая, что навсегда не найти части кода анализатора)