Cегодня Java-разработчики всё чаще используют библиотеки для порождения Java-байткода в рантайме для эффективной реализации различных трюков, которые сложно или невозможно выразить на языке Javа. Но если используя язык Java, компилятор javac гарантирует, что на выходе получится корректный Java-байткод, то спускаясь на уровень непосредственно байткода, вам нужно часто самостоятельно следить за его корректностью. Иначе вы будете получать j.l.VerifyError при загрузке порождённых вами классов, потому что JVM строго следит за корректностью байткода, который она загружает, посредством верификатора Java-байткода. Таким образом, порождая байткод, вам часто недостаточно просто знать семантику байткодных инструкций, вам также нужно знать, как работает Java bytecode-верификатор, какой байткод он считает корректным, а какой — нет.
Здесь мы разберёмся, какую миссию в JVM несёт верификатор байткода, когда и как он работает, может ли повлиять на производительность вашего приложения и почему опасно его отключать.