1

所以我想用CRIU做一个JVM进程的快照,以后再恢复。为此,我编写了一个小程序,它只做每秒打印一次计数器:

package some;

public class Fun {
    public static void main(String[] args) throws InterruptedException {
        for(int i = 0; i < Integer.valueOf(args[0]); i++) {
            System.out.println("Counter: "+i);
            Thread.sleep(1000);
        }       
    }   
}

现在,当我运行程序$ java some.Fun 3000时,程序开始向我显示秒数,到目前为止一切都很好。

现在,当我想用​​ criu 存储进程时,我会$ ps -aux找到我的 java 进程的 PID(在本例中为 3503)并在其上调用 criu $ criu dump -t 3503 -o dump.log --shell-job。这样做后,带有计数器的终端停止计数,打印Killed并似乎终止。

此时在我调用 criu 的文件夹中,我得到了一些转储文件,可用于恢复进程$ criu restore -o dump.log --shell-job

当我这样做时,将创建一个具有新 PID 的新进程,并且计数器从它停止的那一刻开始计数,就像它应该的那样。好的!

但是,假设我终止了该进程并尝试使用相同的转储文件来恢复该进程。如果我这样做,criu 会立即终止并显示 message Aborted (core dumped)。如果我尝试在另一台机器上使用相同的 java 版本传输文件并尝试在那里运行它,也会发生同样的情况......

现在我的问题是:应该是这样吗?我们应该能够只恢复一次状态吗?还是我做错了什么?先感谢您!

4

1 回答 1

1

您需要禁用 JVM 的 perfdata 功能。

$ java -XX:-UsePerfData some.Fun 3000

这将抑制/tmp/hsperfdata_userid目录的创建。

出现此问题的原因是,当 CRIU 检查点进程树时,它会存储所有打开文件描述符的信息,并且在还原期间它要求所有文件都存在(并且具有相同的大小)。

当您第一次恢复您的 java 应用程序时,临时 hsperfdata 文件仍然存在并且一切正常,但是当您终止您的应用程序时,这些临时文件也被删除了。

于 2019-06-23T10:02:40.317 回答