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!
答案 0 :(得分:0)
您需要禁用JVM的perfdata功能。
$ java -XX:-UsePerfData some.Fun 3000
这将禁止创建/tmp/hsperfdata_userid
目录。
之所以会出现此问题,是因为CRIU在检查进程树时会存储所有打开的文件描述符的信息,而在还原过程中,它要求所有文件都存在(且大小相同)。
当您第一次还原Java应用程序时,临时的hsperfdata文件仍然存在,并且一切正常。但是,当您终止应用程序时,这些临时文件也将被删除。