2015-06-09 8 views
5

Beim Lesen der JVM-Spezifikation (wie man es tut) war ich sehr überrascht, als ich auf die 7 iconst_<i> Opcodes stieß. Schließlich gibt es nur ein Byte zum Spielen.Warum hat die JVM die iconst_2 - iconst_5 Opcodes?

Ich schreibe sehr selten die Literale für 2, 3, 4 oder 5 in meinem Code. Ich kann verstehen, warum -1, 0 und 1 vielleicht speziell behandelt werden, aber es scheint mir erstaunlich, dass die Designer 4 kostbare Opcodes auf Zahlen, die nur ganz klein sind, blasen wollen.

Weiß jemand, ob es einen guten Grund dafür gibt? Unterschätze ich den Nutzen von diesen?

+0

Es gibt 255 op-Codes verfügbar denken würde. Es ist ziemlich schwierig, sie bei der Entwicklung eines VM-Befehlssatzes zu verwenden. Offensichtlich dachte Jim Gosling, dass es eine gute Dea war, und es ist kostenlos, bis du leer bist, wie kostenlose Theaterkarten verschenkt, also warum nicht? – EJP

Antwort

4

Ich denke, Ihre Annahme ist richtig: nur um den Bytecode kleiner und Java-Interpreter ein kleines bisschen schneller zu machen (es gab keine JIT-Compiler diese Zeiten). Beachten Sie, dass diese Bytecodes viel häufiger als erwartet verwendet werden können. Betrachten wir zum Beispiel den folgenden Code:

int[] a = {10, 20, 30, 40}; 

effektiv es etwas kompiliert wie:

int[] a = new int[4]; 
a[0] = 10; 
a[1] = 20; 
a[2] = 30; 
a[3] = 40; 

Also hier iconst_0 zu iconst_4 verwendet werden, auch wenn Sie keine solche Konstanten im Quellcode haben.

+0

Guter Punkt, danke. – user1675642

3

Hope this Ihre Frage klären, warum die 4 Opcode verschwenden ..

Siehe Byte-Code dieses Codes

public static void main(String[] args) { 
     int b = 20; 
     int c = 5; 
     int d= 6; 
    } 

Teil von Byte-Code

0: bipush  20 
2: istore_1 
3: iconst_5 
4: istore_2 
5: bipush  6 
7: istore_3 

Wie Sie sehen können für Nummer größer 5 beginnt es mit bipush, die in der Regel weniger effizient als die entsprechende iconst_<n> sind und auch mehr Bytes in der Klassendatei aufnehmen.

BIPUSH byte1 erweitert byte1 in einem int und dann schiebt es auf die Stapel, weil jeder Schlitz auf dem Java-Stack 32 Bit breit ist (JVM ist Stack-basierte virtuelle Maschinen)

Und um zu sehen, wenn bipush mehr Byte nimmt ..

finden sie in der Klasse Dateigröße von zwei folgenden Code ein. (diese Größe sind auf meiner 64-Bit-Maschine .. es kann auf Ihrem Rechner unterscheiden sich aber der Unterschied wird sam sein e)

public class Test2 { 

    public static void main(String[] args) { 
     int b = 5; 

    } 

} 

Größe 406 Bytes

jetzt, wenn ich ersetzen b =6; Die Größe der gleichen Klassendatei wird 407 bytes, die bis b=127 konstant bleibt, die auch bipush verwendet.Dieser Unterschied in der Größe ist aufgrund der Tatsache, dass BIPUSH 2 Bytes, einen Byte Opcode, zweiten Byte sofort constat Wert

BIPUSH Format:

bipush 
byte 

wie können Sie von der Linie 5: bipush 6 in Bytecode sehen während iconst_<n> nur 1 Byte verwendet.

So solche Bytecodes sind für einige häufig geschoben Zahlen definiert, auf die Effizienz der Bytecode-Ausführung erhöhen und die Größe von Bytecode Ströme reduzieren.

und als Tagir sagte, diese Zahlen häufiger verwendet werden würde, als Sie