2013-06-03 17 views
6

Powiedziano mi, że słowo kluczowe volatile może dodać barierę pamięci przed operacją zapisu zmiennej. Więc piszę kod:Jak dekompilować zmienną zmienną w Javie?

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(); 
    } 
} 

a następnie dekompilacji:

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 

} 

nie widzę nic związanego bariera pamięci, a następnie usunąć ten volatile i dekompilacji go ponownie, kod bajtowy w ogóle się nie zmienia.

Jak mogę znaleźć cokolwiek w kodzie bajtowym?

Odpowiedz

9

Koncepcja bariera pamięci nie istnieje na poziomie specyfikacji Java. Jest to szczegół implementacji niskiego poziomu niektórych architektur procesorów, takich jak architektura NUMA, która jest obecnie najbardziej popularna.

Dlatego należy przyjrzeć się kodowi maszynowemu wyprodukowanemu przez kompilator Just-in-Time wewnątrz konkretnej implementacji JVM, takiej jak HotSpot na architekturze x86. Tam, jeśli jesteś wystarczająco zaawansowany, aby interpretować kod maszynowy x86, zobaczysz przejaw bariery pamięci.

+1

Dzięki, @Marko, mimo że bariera pamięci jest produkowana przez JIT, myślę, że powinna istnieć jakaś składnia w kodzie bajtowym, aby wskazać, że zmienna jest zmienna, czyż nie? Kod bajtowy taki sam jak nieulotny, jak JVM może wiedzieć, że jest niestabilny? : D – MrROY

+2

Jest to flaga na samej zmiennej, a nie na kodzie, który uzyskuje do niej dostęp. –

+0

Czy narzędzie do dekompilacji może pokazać mi szczegóły zmiennej lotnej? – MrROY

1

Dodanie volatile do pola nie zmienia kodu bajtowego Java, który odczytuje lub zapisuje pole. W razie potrzeby zmienia jedynie interpretację programu przez kompilację JVM lub JIT. Wpływa również na optymalizacje.

Field flags

Read and Write synchronization

6

Jeśli przetestować go z javap i odpowiednich opcji, flaga ACC_VOLATILE jest widoczny:

javap -v -p Test 

druk:

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

(flagi zdefiniowane w jvm spec Chapter 4. The class File Format)