J'ai vu de nombreuses applications qui prennent des cours d'instruments et prennent -javaagent
comme paramètre lors du chargement, mettez également un -noverify
à la ligne de commande.
Le document Java doc indique que -noverify
désactive la vérification des classes.
Mais pourquoi voudrait-on désactiver la vérification même s'il s'agit de classes d'instrumentation?
Le temps de démarrage, je dirais. La vérification de l'exactitude des classes prend un certain temps lors du chargement de la classe. Étant donné que les classes peuvent être chargées de manière paresseuse (pas au démarrage de l'application, mais lors de leur première utilisation), cela peut entraîner des retards d'exécution inattendus et indésirables.
En fait, la classe n'a pas besoin d'être vérifiée en général. Le compilateur n'émettra aucun bytecode ou construction de classe invalide. La raison de la vérification est que la classe peut être construite sur un seul système, hébergée en ligne et vous est transmise via Internet non protégé. Sur ce chemin, un attaquant malveillant pourrait modifier le bytecode et créer quelque chose que le compilateur pourrait ne jamais créer; quelque chose qui peut planter la JVM ou peut-être contourner les restrictions de sécurité. Ainsi, la classe est vérifiée avant d'être utilisée. S'il s'agit d'une application locale, il n'est généralement pas nécessaire de vérifier à nouveau le bytecode.
Lorsqu'il est utilisé conjointement avec -javaagent
, il est très probable pas pour des raisons de performances, mais parce que l'agent crée intentionnellement un bytecode "invalide".
Il convient de noter qu'un bytecode non valide peut toujours s'exécuter correctement, car certaines des règles de vérification sont assez strictes. Par exemple, this
ne doit pas être accessible dans un constructeur avant l'appel du super-constructeur, car les variables ne sont pas initialisées à ce stade. Mais il y a peut-être encore d'autres choses que vous voulez faire (voir l'exemple JRebel). Ensuite, vous utilisez -noverify
pour contourner cette règle.
Débogage! En fait, c'est ce que je fais maintenant et comment je suis tombé sur cette question. Chez Terracotta, nous faisons beaucoup d'instruments de bytecode, et parfois cela aide à désactiver le vérificateur lorsque nous déboguons nos adaptateurs de classe, afin que nous puissions voir où exactement ils échouent au moment de l'exécution.
Vous avez raison, nous voulons que le vérificateur reste en production.
Utiliser JRebel sans -noverify
donnera cet avertissement au démarrage:
JRebel: '-noverify' manquant, changer/ajouter/supprimer des constructeurs ne sera pas activé!
Il semble donc que -noverify
permet à la ré-instrumentation du bytecode de faire certaines choses qui autrement ne seraient pas possibles.
Le temps de démarrage était un peu un problème. Cependant, les vérificateurs sont désormais plus rapides, tout comme les processeurs. Le code compilé avec JDK6 javac inclura par défaut des informations supplémentaires pour accélérer l'étape du vérificateur. Apache Harmony utilise simplement un algorithme de vérification beaucoup plus rapide.
Certaines versions très anciennes de javac produisaient un bytecode incorrect. En effet, Sun PlugIn inclut toujours du code de correction pour vérifier certains fichiers de classe cassés.
Le nouveau vérificateur introduit dans Java 6 est très compliqué à traiter pour les manipulations de code.
Jetez un oeil à cela: http://chrononsystems.com/blog/Java-7-design-flaw-leads-to-huge-backward-step-for-the-jvm
et le rapport de bogue associé: http://bugs.Sun.com/view_bug.do?bug_id=8009595