简体   繁体   English

Java JVM 热交换行为

[英]Java JVM HotSwap behaviour

I tried Javas Hotswap today, and its working quite nice.我今天尝试了 Javas Hotswap,它工作得很好。 During my testing i stumbled upon a rather weird behaviour.在我的测试过程中,我偶然发现了一个相当奇怪的行为。 This is my Code:这是我的代码:

public class Test extends JFrame implements ActionListener{

private JButton c;
private int f =1;
/**
 * @param args
 */
public static void main(String[] args) {
    Test t = new Test();
}

public Test(){
    this.setPreferredSize(new Dimension(800, 600));
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    c = new JButton("Click");
    c.addActionListener(this);
    this.add(c);
    this.pack();
    this.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
    c.setText(String.valueOf(f++));

}

}

Note the line c.setText(String.valueOf(f++));注意行c.setText(String.valueOf(f++)); near the end.接近尾声。 If i switch that to f-- while the program is running, i notice that on the first click on the button after the change, the value is still counting up.如果我在程序运行时将其切换为f-- ,我注意到在更改后第一次单击按钮时,该值仍在递增。 The Clicks after that however are counting correctly.然而,之后的点击次数计算正确。 The same occurs when changing it back.将其改回时也会发生同样的情况。

The next thing i noticed is: if i change the code to this: c.setText(String.valueOf(f+=1));接下来我注意到的是:如果我将代码更改为: c.setText(String.valueOf(f+=1)); , run the JVM and Hotswap it to c.setText(String.valueOf(f-=1)); ,运行 JVM 并将其热交换为c.setText(String.valueOf(f-=1)); the change is directly applied, with no click-delay.直接应用更改,没有点击延迟。

My question is now: What exactly causes this behaviour?我现在的问题是:究竟是什么导致了这种行为? And what are the differences between f++ and f+=1 on JVM Code Level?在 JVM 代码级别上, f++f+=1有什么区别?

Using javap on this code:在此代码上使用 javap:

public static void main(String[] args) throws Exception {
    int i = 0;
    i++;
    System.out.println(i);
    i+=1;
    System.out.println(i);
}

returns回报

  0: iconst_0
  1: istore_1
  2: iinc          1, 1
  5: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
  8: iload_1
  9: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
 12: iinc          1, 1
 15: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
 18: iload_1
 19: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
 22: return

==> no difference ==> 没有区别

Have you turned off all optimizations?您是否关闭了所有优化? There are quite a few different tricks the JIT compiler can do behind the scenes dynamically so the resulting underlying code changes multiple times during execution. JIT 编译器可以在幕后动态执行许多不同的技巧,因此生成的底层代码在执行期间会多次更改。

Using actionPerformed() you are dealing with asyncronous events which can make following the execution path more difficult even without hotswap issues.使用 actionPerformed() 您正在处理异步事件,即使没有热交换问题,这也会使执行路径变得更加困难。

Do the same test code做同样的测试代码

c.setText(String.valueOf(f++)); 

but do it inside a big loop with a breakpoint set, that way you can test out the variations with fewer moving parts.但是在一个带有断点设置的大循环中进行,这样你就可以用更少的移动部件来测试变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM