【问题标题】:Java JVM HotSwap behaviourJava JVM 热交换行为
【发布时间】:2012-04-22 22:32:40
【问题描述】:

我今天尝试了 Javas Hotswap,它的工作非常好。在我的测试中,我偶然发现了一个相当奇怪的行为。这是我的代码:

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++));

}

}

注意接近末尾的c.setText(String.valueOf(f++)); 行。如果我在程序运行时将其切换为f--,我注意到在更改后第一次单击按钮时,该值仍在计数。然而,之后的点击计数正确。改回来的时候也是这样。

我注意到的下一件事是:如果我将代码更改为:c.setText(String.valueOf(f+=1));,运行 JVM 并将其热交换到c.setText(String.valueOf(f-=1));,则直接应用更改,没有点击延迟。

我现在的问题是:究竟是什么导致了这种行为? f++f+=1 在 JVM 代码级别有什么区别?

【问题讨论】:

  • Precedence of ++ and -- operators in Java 的可能重复项......一般来说只是运算符。
  • 我认为这是一个不同的问题,因为重点更多的是热插拔 JVM 的行为,而不是运算符优先级。

标签: java hotswap


【解决方案1】:

您是否关闭了所有优化?有quite a few 不同的tricks JIT compiler 可以在幕后动态执行,因此生成的underlying code 在执行期间会更改multiple times

使用 actionPerformed() 您正在处理异步事件,即使没有热插拔问题,这也会使执行路径变得更加困难。

做同样的测试代码

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

但是在设置了断点的大循环中进行,这样你就可以用更少的移动部件来测试变化。

【讨论】:

    【解决方案2】:

    在此代码上使用 javap:

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

    返回

      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
    

    ==> 没有区别

    【讨论】:

    • 我把 f++++f 混淆了,我的错,但这回答了我的一半问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    相关资源
    最近更新 更多