Как байт-код проходит проверку в JVM?

Вы также можете попробовать Perl

perl -lne ' while(/(\S+)/g) { $x=$1; 
      while($x=~/\b(?=(\w{4}))|\B(?=(\w{4}))\B|(?=(\w{4}))\b/g) { $kv{"$1$2$3"}++ }} 
       END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

$ cat test.txt
no apples
no apples
mango is great
banana is expensive
test

$ perl -lne ' while(/(\S+)/g) { $x=$1; 
     while($x=~/\b(?=(\w{4}))|\B(?=(\w{4}))\B|(?=(\w{4}))\b/g) { $kv{"$1$2$3"}++ }}
       END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
$kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
}" for(keys %kv) } ' test.txt nsiv 1 xpen 1 reat 1 ensi 1 sive 1 ples 2 pple 2 test 1 appl 2 expe 1 anan 1 mang 1 ango 1 bana 1 pens 1 grea 1 nana 1 $

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
$kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

$ cat test.txt
no apples
no apples
mango is great
banana is expensive
test

$ perl -lne ' while(/(\S+)/g) { $x=$1; 
     while($x=~/\b(?=(\w{4}))|\B(?=(\w{4}))\B|(?=(\w{4}))\b/g) { $kv{"$1$2$3"}++ }}
       END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
$kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
}" for(keys %kv) } ' test.txt nsiv 1 xpen 1 reat 1 ensi 1 sive 1 ples 2 pple 2 test 1 appl 2 expe 1 anan 1 mang 1 ango 1 bana 1 pens 1 grea 1 nana 1 $

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
}" for(keys %kv) } ' file

с вашими заданными входами

$ cat test.txt
no apples
no apples
mango is great
banana is expensive
test

$ perl -lne ' while(/(\S+)/g) { $x=$1; 
     while($x=~/\b(?=(\w{4}))|\B(?=(\w{4}))\B|(?=(\w{4}))\b/g) { $kv{"$1$2$3"}++ }}
       END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
$kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
}" for(keys %kv) } ' test.txt nsiv 1 xpen 1 reat 1 ensi 1 sive 1 ples 2 pple 2 test 1 appl 2 expe 1 anan 1 mang 1 ango 1 bana 1 pens 1 grea 1 nana 1 $

Вы можете параметризовать внутри блока BEGIN как

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112] $kv{

Вы также можете попробовать Perl

[110]

с вашими заданными входами

[111]

Вы можете параметризовать внутри блока BEGIN как

[112]}" for(keys %kv) } ' test.txt great 1 pples 2 apple 2 expen 1 nsive 1 banan 1 anana 1 ensiv 1 pensi 1 xpens 1 mango 1 $
14
задан John Topley 16 April 2009 в 06:45
поделиться

2 ответа

Oracle themselves have a little snippet page on how it works here.

Basically, the JRE doesn't trust the JDK. That's because it has no knowledge of which JDK compiler created the class file. It treats the class file as hostile until verified.

Expanding on that, the bytecode verification is a necessary step to protect from what Sun call a "hostile compiler". Sun's own Java compiler ensures that Java source code doesn't violate the safety rules but, when an application imports a code fragment, it doesn't actually know if the code fragment follows Java language rules for safety. In other words, the code may not have been produced by a trustworthy Java compiler.

In that case, the Java run time system on your machine has to assume the fragment is bad and subjects it to bytecode verification.

The Java virtual machine does not even see the bytecode until it's been through this verification process. Doing this as the bytecode is loaded also has the advantage that a whole lot of run time checks don't need to be performed every time the code is executed. Because it's been verified as correct, it can, once it starts running, run faster than would otherwise be possible.

A rendition of the linked diagram is below:

                    <<<=== Unsafe / Safe ===>>>
                                  \
+---------------+        +-------------------+
|  Java source  |   +--> |   Class loader    | --+
+---------------+   |    | Bytecode verifier |   |
        |           |    +-------------------+   |
        V           |             /              |
+---------------+   |             \              V
| Java compiler |  Network        /    +-------------------+
+---------------+   |             \    |      JVM/JIT      |
        |           |             /    +-------------------+
        V           |             \              |
+---------------+   |             /              V
| Java bytecode | --+             \    +-------------------+
+---------------+                 /    | Operating system  |
                                  \    +-------------------+
                                  /              |
                                  \              V
                                  /    +-------------------+
                                  \    |     Hardware      |
                                  /    +-------------------+
                                  \
                    <<<=== Unsafe / Safe ===>>>
19
ответ дан 1 December 2019 в 09:33
поделиться

The best source of information is probably the relevant section in the JVM specification, 4.10 Verification of class Files.

See the link for details, but broadly:

Linking-time verification enhances the performance of the interpreter. Expensive checks that would otherwise have to be performed to verify constraints at run time for each interpreted instruction can be eliminated. The Java Virtual Machine can assume that these checks have already been performed. For example, the Java Virtual Machine will already know the following:

  • There are no operand stack overflows or underflows.
  • All local variable uses and stores are valid.
  • The arguments to all the Java Virtual Machine instructions are of valid types.

The verifier also performs verification that can be done without looking at the code array of the Code attribute (§4.7.3). The checks performed include the following:

  • Ensuring that final classes are not subclassed and that final methods are not overridden (§5.4.5).
  • Checking that every class (except Object) has a direct superclass.
  • Ensuring that the constant pool satisfies the documented static constraints; for example, that each CONSTANT_Class_info structure in the constant pool contains in its name_index item a valid constant pool index for a CONSTANT_Utf8_info structure.
  • Checking that all field references and method references in the constant pool have valid names, valid classes, and a valid type descriptor.
9
ответ дан 1 December 2019 в 09:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: