2013-06-03 5 views
6

Mi è stato detto che la parola chiave volatile potrebbe aggiungere una barriera di memoria prima di scrivere l'operazione della variabile. Così scrivo il codice:Come decompilare la variabile volatile in Java?

public class Test { 
    private Object o; 

    public Test() { 
     this.o = new Object(); 
    } 

    private volatile static Test t; 

    public static void createInstance() { 
     t = new Test();    // volatile would insert memory barrier here. 
    } 

    public static void main(String[] args) throws Exception { 
     Test.createInstance(); 
    } 
} 

E poi decompilarlo:

Compiled from "Test.java" 
public class Test extends java.lang.Object{ 
public Test(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: new #2; //class java/lang/Object 
    8: dup 
    9: invokespecial #1; //Method java/lang/Object."<init>":()V 
    12: putfield #3; //Field o:Ljava/lang/Object; 
    15: return 

public static void createInstance(); 
    Code: 
    0: new #4; //class Test 
    3: dup 
    4: invokespecial #5; //Method "<init>":()V 
    7: putstatic #6; //Field t:LTest; 
    10: return 

public static void main(java.lang.String[]) throws java.lang.Exception; 
    Code: 
    0: invokestatic #7; //Method createInstance:()V 
    3: return 

} 

non riesco a vedere tutto ciò che riguarda la memoria di barriera, e poi ho rimuovere il volatile e decompilare di nuovo, il codice di byte non cambia affatto.

Come posso trovare qualcosa nel codice byte?

risposta

9

Il concetto di barriera di memoria non esiste al livello delle specifiche Java. È un dettaglio di implementazione di basso livello di alcune architetture della CPU, come l'architettura NUMA che è la più popolare oggi.

Pertanto, è necessario esaminare il codice macchina prodotto da un compilatore Just-in-Time all'interno di un'implementazione JVM specifica, ad esempio HotSpot su un'architettura x86. Lì, se sei abbastanza esperto per interpretare il codice macchina x86, vedresti la manifestazione della barriera di memoria.

+1

Grazie, @Marko, se la barriera di memoria è prodotto da JIT, penso che ci dovrebbe essere qualche sintassi nel bytecode per indicare la variabile è volatile, non è vero? Il codice byte proprio come non volatile, come potrebbe JVM sapere che c'è un volatile? : D – MrROY

+2

È un flag sulla variabile stessa, non sul codice che lo accede. –

+0

C'è qualche strumento decompilare mi potrebbe mostrare dettaglio di variabili volatili? – MrROY

1

Aggiunta volatile al campo non cambia il bytecode Java che legge o scrive il campo. Cambia solo l'interpretazione del programma da parte dell'output di compilazione JVM o JIT, se necessario. Influenza anche le ottimizzazioni.

Field flags

Read and Write synchronization

6

Se si prova con javap e le giuste opzioni, l'ACC_VOLATILE bandiera è visibile:

javap -v -p Test 

stampa:

private static volatile Test t; 
flags: ACC_PRIVATE, ACC_STATIC, ACC_VOLATILE 

(bandiere sono definito nella specifica jvm Chapter 4. The class File Format)