Использование -noverify при запуске Java-приложений - PullRequest
32 голосов
/ 19 ноября 2008

Я видел много приложений, которые принимают классы инструментов и принимают -javaagent в качестве параметра при загрузке, также помещают -noverify в командную строку.

Документ Java говорит, что -noverify отключает проверку класса.

Однако зачем кому-то хотеть отключить проверку, даже если они занимаются инструментарием?

Ответы [ 6 ]

43 голосов
/ 05 декабря 2012

Когда он используется вместе с -javaagent, он, скорее всего, не по соображениям производительности, а потому, что агент намеренно создает «недопустимый» байт-код.

Следует отметить, что недействительный байт-код может все еще выполняться нормально, потому что некоторые из правил проверки являются довольно строгими. Например, this не должен быть доступен в конструкторе до вызова супер-конструктора, потому что переменные не инициализируются в этой точке. Но могут быть и другие вещи, которые вы хотите сделать (см. Пример JRebel). Затем вы используете -noverify, чтобы обойти это правило.

33 голосов
/ 19 ноября 2008

Время запуска, я бы сказал. Проверка правильности классов занимает некоторое время, когда класс загружается. Поскольку классы могут загружаться лениво (не при запуске приложения, а при первом использовании), это может привести к неожиданным и нежелательным задержкам выполнения.

На самом деле класс вообще не нужно проверять. Компилятор не будет выдавать какой-либо недопустимый байт-код или конструкцию класса. Причина проверки заключается в том, что класс может быть построен на одной системе, размещаться в Интернете и передаваться вам через незащищенный Интернет. На этом пути злоумышленник может изменить байт-код и создать то, что компилятор может никогда не создать; что-то, что может привести к сбою JVM или, возможно, обойти ограничения безопасности. Таким образом, класс проверяется перед использованием. Если это локальное приложение, обычно нет необходимости снова проверять байт-код.

5 голосов
/ 02 декабря 2008

Debugging! На самом деле это то, что я делаю сейчас, и как я наткнулся на этот вопрос. В Terracotta мы выполняем много инструментария байт-кода, и иногда это помогает отключить верификатор при отладке наших адаптеров классов, чтобы мы могли видеть, где именно они терпят неудачу во время выполнения.

Вы правы, мы хотим, чтобы верификатор оставался включенным.

3 голосов
/ 29 июля 2011

Использование JRebel без -noverify выдаст это предупреждение при запуске:

JRebel: '-noverify' отсутствует, изменение / добавление / удаление конструкторов не будет включено!

Похоже, что -noverify позволяет переинструментации байт-кода делать некоторые вещи, которые иначе были бы невозможны.

2 голосов
/ 19 ноября 2013

Новый верификатор, представленный в JAVA 6, очень сложен для обработки манипуляций с кодом.

Взгляните на это: http://chrononsystems.com/blog/java-7-design-flaw-leads-to-huge-backward-step-for-the-jvm

и соответствующий отчет об ошибке: http://bugs.sun.com/view_bug.do?bug_id=8009595

2 голосов
/ 19 ноября 2008

Время запуска раньше было проблемой. Однако верификаторы теперь быстрее, как и процессоры. Код, скомпилированный с JDK6, по умолчанию будет включать в себя дополнительную информацию, чтобы сделать шаг проверки быстрее. Apache Harmony просто использует гораздо более быстрый алгоритм проверки.

Некоторые очень старые версии javac выдают неправильный байт-код. Действительно, подключаемый модуль Sun по-прежнему содержит код исправления, позволяющий проверить некоторые поврежденные файлы классов.

...