2013-06-03 24 views
6

Tôi đã được thông báo rằng từ khóa volatile có thể thêm hàng rào bộ nhớ trước khi ghi hoạt động của biến. Vì vậy, tôi viết mã:Làm thế nào để dịch ngược biến dễ bay hơi trong 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(); 
    } 
} 

Và sau đó dịch ngược nó:

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 

} 

Tôi không thể nhìn thấy bất cứ điều gì liên quan đến rào cản bộ nhớ, và sau đó tôi loại bỏ các volatile và ngược lại, các mã byte không thay đổi chút nào.

Làm cách nào tôi có thể tìm thấy bất kỳ thứ gì trong mã byte?

Trả lời

9

Khái niệm về rào cản bộ nhớ không tồn tại ở cấp độ đặc tả Java. Nó là một chi tiết thực hiện ở mức độ thấp của một số kiến ​​trúc CPU nhất định, chẳng hạn như kiến ​​trúc NUMA phổ biến nhất hiện nay.

Vì vậy, bạn sẽ cần phải xem mã máy được tạo bởi trình biên dịch Just-in-Time bên trong một triển khai JVM cụ thể, chẳng hạn như HotSpot trên kiến ​​trúc x86. Ở đó, nếu bạn đủ kỹ năng để giải thích mã máy x86, bạn sẽ thấy biểu hiện của rào cản bộ nhớ.

+1

Cảm ơn, @Marko, Mặc dù rào cản bộ nhớ được sản xuất bởi JIT, tôi nghĩ rằng cần có một số cú pháp trong mã byte để cho biết biến là dễ bay hơi, phải không? Mã byte chỉ giống như non-volatile, làm thế nào JVM có thể biết có một biến động? : D – MrROY

+2

Đó là một lá cờ trên biến, không phải trên mã truy cập vào nó. –

+0

Có công cụ dịch ngược nào có thể chỉ cho tôi chi tiết biến dễ bay hơi không? – MrROY

1

Thêm volatile vào trường không thay đổi mã byte Java mà đọc hoặc viết trường. Nó chỉ thay đổi cách giải thích của chương trình bằng đầu ra biên dịch JVM hoặc JIT nếu cần. Nó cũng ảnh hưởng đến tối ưu hóa.

Field flags

Read and Write synchronization

6

Nếu bạn thử nghiệm nó với javap và các tùy chọn bên phải, ACC_VOLATILE cờ có thể nhìn thấy:

javap -v -p Test 

in:

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

(cờ là được định nghĩa trong thông số jvm Chapter 4. The class File Format)

Các vấn đề liên quan