インストゥルメント クラスを取り-javaagent
、読み込み時にパラメータとして取り-noverify
、コマンド ラインに a を追加する多くのアプリを見てきました。
Java doc によると、-noverify
クラス検証がオフになります。
しかし、クラスを計測している場合でも、なぜ検証をオフにしたいのでしょうか?
インストゥルメント クラスを取り-javaagent
、読み込み時にパラメータとして取り-noverify
、コマンド ラインに a を追加する多くのアプリを見てきました。
Java doc によると、-noverify
クラス検証がオフになります。
しかし、クラスを計測している場合でも、なぜ検証をオフにしたいのでしょうか?
起動時間、私は言うだろう。クラスがロードされると、クラスが正しいことを確認するのに時間がかかります。クラスは (アプリの開始時ではなく、初めて使用するときに) 遅延形式で読み込まれる可能性があるため、予期しない望ましくない実行時の遅延が発生する可能性があります。
実際、クラスは一般的にチェックする必要はありません。コンパイラは、無効なバイトコードまたはクラス コンストラクトを発行しません。検証の理由は、クラスが 1 つのシステム上で構築され、オンラインでホストされ、保護されていないインターネットを介して送信される可能性があるためです。このパスでは、悪意のある攻撃者がバイトコードを変更し、コンパイラが決して作成しないものを作成する可能性があります。JVM をクラッシュさせたり、セキュリティ制限を回避したりする可能性があります。したがって、クラスは使用前に検証されます。これがローカル アプリケーションの場合、通常、バイトコードを再度チェックする必要はありません。
と組み合わせて使用する場合-javaagent
、パフォーマンス上の理由ではなく、エージェントが意図的に「無効な」バイトコードを作成するためです。
一部の検証ルールは非常に厳密であるため、無効なバイトコードが正常に実行される可能性があることに注意してください。たとえば、this
この時点では変数が初期化されていないため、スーパーコンストラクターが呼び出される前にコンストラクターでアクセスしてはなりません。しかし、他にもやりたいことがあるかもしれません (JRebel の例を参照してください)。次に、-noverify
そのルールを回避するために使用します。
JRebelを使用せず-noverify
に使用すると、起動時に次の警告が表示されます。
JRebel:'-noverify'がありません、コンストラクターの変更/追加/削除は有効になりません!
したがって-noverify
、バイトコードの再インストルメンテーションが、他の方法では不可能ないくつかのことを実行できるようになります。
デバッグ中!実際、それが私が今やっていることであり、この質問に出くわした方法です。Terracotta では多くのバイトコード インストルメンテーションを行っており、クラス アダプターをデバッグするときに検証ツールをオフにすると、実行時に失敗した場所を正確に確認できる場合があります。
おっしゃる通り、ベリファイアを本番環境に残しておきたいのです。
起動時間は少し問題でした。ただし、プロセッサと同様に、ベリファイアも高速になりました。JDK6 javacでコンパイルされたコードには、デフォルトで、ベリファイアのステップを高速化するための追加情報が含まれます。Apache Harmonyは、はるかに高速な検証アルゴリズムを使用しています。
非常に古いバージョンのjavacの中には、誤ったバイトコードを生成するものがありました。実際、Sun PlugInには、壊れたクラスファイルを検証するための修正コードがまだ含まれています。
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