Использование-noverify при запуске java-приложений
Я видел много приложений, которые берут классы инструментов и принимают -javaagent
в качестве параметра при загрузке тоже поставил -noverify
в командной строке.
Java doc говорит, что -noverify
отключает проверку класса.
однако почему кто-то хочет отключить проверку, даже если они инструментируют классы?
6 ответов
время запуска, я бы сказал. Проверка правильности классов занимает некоторое время при загрузке класса. Поскольку классы могут загружаться лениво (не при запуске приложения, а при первом использовании), это может привести к неожиданным и нежелательным задержкам выполнения.
на самом деле класс не нужно проверять вообще. Компилятор не будет выдавать недопустимый байт-код или конструкцию класса. Причина проверки заключается в том, что класс может быть построен на одной системе, получить размещен в интернете и передается вам через незащищенный интернет. На этом пути злоумышленник может изменить байт-код и создать то, что компилятор может никогда не создать; что-то, что может привести к сбою JVM или, возможно, обойти ограничения безопасности. Таким образом, класс проверяется перед использованием. Если это локальное приложение, обычно нет необходимости снова проверять байт-код.
, когда он используется в сочетании с -javaagent
, Это, скорее всего,не по соображениям производительности, но потому, что агент намеренно создает "недопустимый" байт-код.
следует отметить, что недопустимый байт-код может по-прежнему выполняться нормально, потому что некоторые правила проверки довольно строги. Например, this
не должен быть доступен в конструкторе до вызова супер-конструктора, потому что переменные не инициализируются в этот момент. Но все равно может быть другие вещи, которые вы хотите сделать (см. Пример JRebel). Затем вы используете -noverify
чтобы обойти это правило.
отладка! В том, что я делаю сейчас, и как я наткнулся на этот вопрос. В Terracotta мы делаем много инструментов байт-кода, и иногда это помогает отключить верификатор при отладке наших адаптеров классов, чтобы мы могли видеть, где именно они терпят неудачу во время выполнения.
вы правы, мы хотим, чтобы верификатор оставался в производстве.
использование JRebel без -noverify
даст это предупреждение при запуске:
JRebel: '-noverify' отсутствует, изменение/добавление/удаление конструкторов не будет включен!
Так выходит, что -noverify
позволяет bytecode re-instrumentation делать некоторые вещи, которые в противном случае были бы невозможны.
время запуска раньше было немного проблемой. Однако верификаторы теперь быстрее, как и процессоры. Код, скомпилированный с jdk6 javac, по умолчанию будет включать дополнительную информацию, чтобы сделать шаг верификатора быстрее. Apache Harmony просто использует гораздо более быстрый алгоритм проверки.
некоторые очень старые версии javac произвели неправильный байт-код. Действительно, плагин Sun по-прежнему включает в себя код исправления, чтобы сделать некоторые сломанные файлы классов проверить.
новый верификатор, который представлен в 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