Jvm Java应用程序的CRIU使用

Jvm Java应用程序的CRIU使用,jvm,migration,restore,checkpointing,Jvm,Migration,Restore,Checkpointing,因此,我想使用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++) { Syste

因此,我想使用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);
        }       
    }   
}
打包一些;
公共课乐趣{
公共静态void main(字符串[]args)引发InterruptedException{
对于(int i=0;i
现在,当我运行程序m
$javasome.fun3000
时,程序开始向我显示秒数,到目前为止还不错

现在,当我想用criu存储进程时,我会找到java进程的PID(本例中为3503),并调用criu。执行此操作后,带计数器的终端停止计数,打印
已终止
,并似乎终止

此时,在我调用criu的文件夹中,我得到了一些转储文件,可以用来还原进程
$criu restore-o dump.log--shell作业

当我这样做的时候,一个新的进程和一个新的PID被创建,计数器从它停止的那一刻开始计数,就像它应该的那样。很好

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

现在我的问题是:应该是这样吗?我们应该能够恢复一次状态吗?还是我做错了什么?
提前谢谢你

您需要禁用JVM的perfdata功能

$java-XX:-UsePerfDatasome.Fun 3000

这将禁止创建
/tmp/hsperfdata\u userid
目录

出现此问题的原因是,当CRIU检查一个进程树时,它会存储所有打开的文件描述符的信息,并且在恢复过程中,它要求所有文件都存在(并且大小相同)

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