CRIU usage for Java application

时间:2019-04-08 12:58:05

标签: jvm migration restore checkpointing

So I want to use CRIU to make a snapshot of a JVM process and restore it later. For this purpose I wrote a little program which does nothing more but printing the counter every second:

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

Now when I run the programm $ java some.Fun 3000 the program starts showing me the seconds, so far so good.

Now when I want to store the process with criu, i do $ ps -aux, find the PID of my java process (3503 in this case) and call criu on it $ criu dump -t 3503 -o dump.log --shell-job. After doing so, the terminal with the counter stops counting, prints Killed and seems to terminate.

At this point in the folder where i called criu, i got some dump files which I can use to restore the process $ criu restore -o dump.log --shell-job

When I do so, a new process with a new PID is created, and the counter is starts counting from the moment it stopped, as it is supposed to be. Nice!

However, lets say I kill the process and try using the same dump files to restore the process. If I do this, criu terminates right away with the message Aborted (core dumped). Same happens if I try transfer the files on another machine, with the same java version and try to run it there...

Now my question is: is it supposed to be so? Are we supposed to be able to restore the state just once? Or am I doing something wrong? Thank you in advance!

1 个答案:

答案 0 :(得分:0)

您需要禁用JVM的perfdata功能。

$ java -XX:-UsePerfData some.Fun 3000

这将禁止创建/tmp/hsperfdata_userid目录。

之所以会出现此问题,是因为CRIU在检查进程树时会存储所有打开的文件描述符的信息,而在还原过程中,它要求所有文件都存在(且大小相同)。

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