我见过很多应用程序类的应用程序,并在加载时将-javaagent
作为参数,并将-noverify
放入命令行。
Java doc说-noverify
关闭了类验证。
然而,为什么有人想要关闭验证,即使他们正在检测课程?
答案 0 :(得分:43)
当它与-javaagent
一起使用时,出于性能原因很可能不,但因为代理故意创建“无效”字节码。
应该注意的是,无效的字节码可能仍然可以正常执行,因为某些验证规则非常严格。例如,在调用超级构造函数之前,不能在构造函数中访问this
,因为此时变量未初始化。但是仍然可能还有其他事情要做(参见JRebel示例)。然后,您使用-noverify
来规避该规则。
答案 1 :(得分:33)
启动时间,我会说。在加载类时,验证类是否正确需要一些时间。由于类可能以惰性方式加载(不是在应用程序启动时加载,而是在第一次使用时),这可能会导致意外和意外的运行时延迟。
实际上这个课程一般不需要检查。编译器不会发出任何无效的字节码或类构造。验证的原因是该类可以构建在一个系统上,在线托管并通过未受保护的互联网传输给您。在此路径上,恶意攻击者可能会修改字节码并创建编译器可能永远不会创建的内容;可能导致JVM崩溃或可能绕过安全限制的东西。因此,在使用之前验证该类。如果这是本地应用程序,通常不需要再次检查字节码。
答案 2 :(得分:5)
调试!事实上,这就是我现在正在做的事情,以及我如何偶然发现这个问题。在Terracotta,我们做了很多字节码检测,有时它会在我们调试类适配器时关闭验证器,因此我们可以看到它们在运行时的确切位置。
你是对的,我们希望验证者继续留在生产中。
答案 3 :(得分:3)
使用不带-noverify
的JRebel会在启动时发出此警告:
JRebel:'-noverify'缺失,不会启用更改/添加/删除构造函数!
看来-noverify
允许字节码重新检测做一些本来不可能的事情。
答案 4 :(得分:2)
启动时间曾经是一个问题。但是,验证器现在更快,处理器也是如此。使用JDK6 javac编译的代码默认包含额外信息,以使验证程序更快。 Apache Harmony只使用更快的验证算法。
一些非常旧版本的javac产生了错误的字节码。实际上,Sun PlugIn仍然包含修复代码,以便对一些损坏的类文件进行验证。
答案 5 :(得分:2)
JAVA 6中引入的新验证程序处理代码操作非常复杂。
看看这个: http://chrononsystems.com/blog/java-7-design-flaw-leads-to-huge-backward-step-for-the-jvm