启动 Java 应用程序时使用 -noverify
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/300639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use of -noverify when launching java apps
提问by pdeva
I have seen many apps that take instrument classes and take -javaagent
as a param when loading also put a -noverify
to the command line.
我已经看到许多应用程序-javaagent
在加载时将乐器类作为参数也将 a 放入-noverify
命令行。
The Java doc says that -noverify
turns off class verification.
Java 文档说-noverify
关闭类验证。
However why would anyone want to turn off verification even if they are instrumenting classes?
但是,为什么有人会想要关闭验证,即使他们正在检测类?
采纳答案by Mecki
Start-up time, I'd say. Verification that classes are correct takes some time when the class is loaded. Since classes might be loaded in a lazy fashion (not on app start, but when being used for the first time), this might cause unexpected and undesired runtime delays.
启动时间,我会说。加载类时,验证类是否正确需要一些时间。由于类可能以惰性方式加载(不是在应用程序启动时,而是在第一次使用时),这可能会导致意外和不希望的运行时延迟。
Actually the class does not need to be checked in general. The compiler will not emit any invalid bytecode or class construct. The reason for verification is that the class may be build on one system, get hosted online and is transmitted to you through the unprotected internet. On this path, a malicious attacker might modify the bytecode and create something the compiler might never create; something that can crash the JVM or possibly circumvents security restrictions. Thus the class is verified before it is used. If this is a local application, there is usually no need to check the bytecode again.
实际上类一般不需要检查。编译器不会发出任何无效的字节码或类构造。验证的原因是该课程可能建立在一个系统上,在线托管并通过未受保护的互联网传输给您。在这条路径上,恶意攻击者可能会修改字节码并创建编译器可能永远不会创建的内容;可能会导致 JVM 崩溃或可能绕过安全限制的东西。因此,在使用该类之前会对其进行验证。如果这是本地应用程序,通常不需要再次检查字节码。
回答by Tom Hawtin - tackline
Start up time used to be a bit of an issue. However, verifiers are now faster, as are processors. Code compiled with JDK6 javac will by default include extra information to make the verifier step faster. Apache Harmony just uses a much faster verification algorithm.
启动时间曾经是一个问题。但是,验证器现在更快,处理器也是如此。默认情况下,使用 JDK6 javac 编译的代码将包含额外信息以使验证器步骤更快。Apache Harmony 只是使用了更快的验证算法。
Some very old versions of javac produced incorrect bytecode. Indeed the Sun PlugIn still includes fix-up code to make some broken class files verify.
一些非常旧的 javac 版本产生了不正确的字节码。事实上,Sun PlugIn 仍然包含修复代码来验证一些损坏的类文件。
回答by Scott Bale
Debugging! In fact that's what I'm doing now, and how I stumbled across this question. At Terracotta we do a lot of bytecode instrumentation, and sometimes it helps to turn off the verifier as we debug our class adapters, so we can see where exactly they fail at runtime.
调试!事实上,这就是我现在正在做的事情,以及我是如何偶然发现这个问题的。在 Terracotta,我们进行了大量字节码检测,有时在调试类适配器时关闭验证器会有所帮助,这样我们就可以查看它们在运行时究竟在哪里失败。
You're right, we want the verifier to remain on in production.
你说得对,我们希望验证器继续在生产中运行。
回答by Esko Luontola
Using JRebel without -noverify
will give this warning on startup:
使用 JRebel without-noverify
将在启动时发出此警告:
JRebel: '-noverify' missing, changing/adding/removing constructors will not be enabled!
JRebel:缺少“-noverify”,将不会启用更改/添加/删除构造函数!
So appears that -noverify
allows bytecode re-instrumentation to do some things which would otherwise not be possible.
所以看起来-noverify
允许字节码重新检测来做一些否则不可能的事情。
回答by Cephalopod
When it is used in conjunction with -javaagent
, it is most likely notfor performance reasons, but because the agent intentionally creates "invalid" bytecode.
当它与 结合使用时-javaagent
,很可能不是出于性能原因,而是因为代理故意创建“无效”字节码。
It should be noted that invalid bytecode might still execute fine, because some of the verification rules are quite strict. For instance, this
must not be accessed in a constructor before the super-constructor was called, because the variables are not initialized at this point. But there still might be other things you want to do (see the JRebel example). Then, you use -noverify
to circumvent that rule.
需要注意的是,无效的字节码可能仍然可以正常执行,因为一些验证规则非常严格。例如,this
在调用超级构造函数之前不能在构造函数中访问,因为此时变量未初始化。但是您可能还有其他想做的事情(请参阅 JRebel 示例)。然后,您使用-noverify
规避该规则。
回答by Aykut Kllic
The new verifier that is introduced in JAVA 6 is very complicated to process for code manipulations.
JAVA 6 中引入的新验证器处理代码操作非常复杂。
Take a look at this: http://chrononsystems.com/blog/java-7-design-flaw-leads-to-huge-backward-step-for-the-jvm
看看这个:http: //chrononsystems.com/blog/java-7-design-flaw-leads-to-huge-backward-step-for-the-jvm
and the related bug report: http://bugs.sun.com/view_bug.do?bug_id=8009595
以及相关的错误报告:http: //bugs.sun.com/view_bug.do?bug_id=8009595