我可以检测字节码编译日志对指令的重新排序吗?

问题描述 投票:0回答:1

我有下一个代码示例:

class Shared {
    int x;
    int y;

    void increment() {
        x++;
        y++;
    }

    void check() {
        if (y > x) {
            System.out.println("Ooops! y > x");
        }
    }
}

看清楚吗?但是,当我尝试增加并检入两个线程时,这里会发生主要问题:

Shared shared = new Shared();

        Thread writer = new Thread(() -> {
            for (int i = 0; i < N; i++) {
                shared.increment();
            }
        });

        Thread reader = new Thread(() -> {
            for (int i = 0; i < N; i++) {
                shared.check();
            }
        });

writer.start();
reader.start();

您会注意到数据争用(某些情况下指令会重新排序吗?):

1. x++;
2. y++;

现在,我了解特殊的VM标志,这可以帮助我打印JIT编译器日志(-XX:+PrintCompilation)。

...
    120  181       3       Shared::increment (21 bytes)
    120  182       3       Shared::check (20 bytes)
    120  183       4       Shared::increment (21 bytes)
    120  184       4       Shared::check (20 bytes)
    121  181       3       Shared::increment (21 bytes)   made not entrant
    121  182       3       Shared::check (20 bytes)   made not entrant
    121  185     n 0       java.lang.invoke.MethodHandle::linkToStatic(L)L (native)   (static)
    121  184       4       Shared::check (20 bytes)   made not entrant
    122  186       3       Shared::check (20 bytes)
    122  187     n 0       java.lang.Object::clone (native)   
    122  188       4       Shared::check (20 bytes)
    122  189 %     3       Main::lambda$main$0 @ 2 (19 bytes)
    122  190       3       Main::lambda$main$0 (19 bytes)
    123  186       3       Shared::check (20 bytes)   made not entrant
...

好,现在我可以看到增量方法的编译是如何处理的:

    120  181       3       Shared::increment (21 bytes)
    120  183       4       Shared::increment (21 bytes)
    121  181       3       Shared::increment (21 bytes)   made not entrant

我理解正确吗?>>,这里的重新排序是由于tiered compilation?因为increment()-hot方法,所以JIT编译器将分析此信息并使用C2服务器编译器。而且,正如我认为的那样,以这种方式对某些指令进行重新排序,但在某些情况下优化是错误的(made not entrant)。还是我错了?

还有另外一些编译日志:

    138  182       2       Shared::increment (21 bytes)
    138  184       4       Shared::increment (21 bytes)
    138  182       2       Shared::increment (21 bytes)   made not entrant

我有下一个代码示例:Class Shared {int x;诠释无效的增量(){x ++; y ++; } void check(){if(y> x){System.out.println(“ ...

java concurrency jvm jit
1个回答
1
投票

我理解正确吗,这里的重新排序是由于分层编译引起的?

© www.soinside.com 2019 - 2024. All rights reserved.