Как декомпилировать переменную volatile в Java?

мне сказали, что volatile ключевое слово может добавить барьер памяти перед операцией записи переменной. Поэтому я пишу код:

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

и затем декомпилировать его:

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

}

Я не вижу ничего, связанного с барьером памяти, а затем я удаляю volatile и декомпилируйте его снова, байтовый код не изменяется вообще.

как я могу найти что-либо в байт-код ?

3 ответов


концепция барьер памяти не существует на уровне спецификации Java. Это низкоуровневая деталь реализации некоторых архитектур ЦП, таких как архитектура NUMA, которая является наиболее популярной сегодня.

поэтому вам нужно будет посмотреть машинный код, созданный компилятором Just-in-Time внутри конкретной реализации JVM, такой как HotSpot на архитектуре x86. Там, если вы достаточно квалифицированы, чтобы интерпретировать машинный код x86, вы бы посмотрите на проявление барьера памяти.


Если вы протестируете его с помощью javap и правильных опций, флаг ACC_VOLATILE будет виден:

javap  -v -p Test

печати:

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

(флаги определены в спецификации jvm Глава 4. Формат файла класса )


добавлять volatile в поле не изменяется байт-код Java, который читает или записывает поле. При необходимости он изменяет интерпретацию программы только с помощью JVM или JIT-компиляции. Это также влияет на оптимизацию.

поле флагов

синхронизация чтения и записи