将Java程序转储到文件并重新启动

16

我想知道是否有可能将运行中的Java程序转储到文件中,然后稍后重新启动它(同一台机器)。

这听起来有点奇怪,但谁知道呢。

--- 更新 -------

是的,这是一个进程而不是完整系统的休眠功能。但是搜索“hibernate jvm process”,您就会理解我的痛苦。

关于这个问题,Linux上有一个问题(在此处)。简单地说,可以使用CryoPID休眠进程(远非100%可靠)。

几年前在stackoverflow上提出了类似的问题。

我的教育猜测是,在JVM中进行休眠应该更容易,但并非总是可能且不可靠(例如UI和文件)。


序列化应用程序的持久状态是一个选项,但并不是问题的答案。


你的意思是创建一个保存文件吗? - Max
数十年前,我记得读到一些指令,可以在 awk 程序运行时进行核心转储,并从核心文件重新启动它。当时我觉得这相当疯狂。 - Paul Tomblin
这听起来很奇怪。你是在说将正在运行的Java程序的源代码转储到文本文件中,编译此源代码并运行它吗? - Bernard
还是更像进入了休眠状态? - vextorspace
是的,它就像一个处理休眠的过程。 - ic3
10个回答

10

这可能有些过度,但你可以运行类似于VirtualBox并停止/保存该虚拟机。

还有其他选择:
- 来自Apache的JavaFlow应该可以做到这一点,尽管我个人没有尝试过。
- Brakes可能正是你要寻找的。


这个问题/答案还建议采用虚拟机的方式:https://dev59.com/I3RC5IYBdhLWcg3wD8xV - jefflunt

8
任何解决您问题的方案都会有很多限制:所有外部连接可能会在冻结和唤醒尝试中存活或未存活。考虑到另一端的超时,或者即使是停止通信的伙伴——从Web服务器到数据库甚至本地文件等任何东西。
您正在寻求一种通用解决方案,没有任何关于您想要休眠的程序的内部知识。您始终可以序列化您需要重启程序的程序状态的一部分。实现长时间运行计算(如几天或几周)的重启点是常见的技巧。因此,当您运行了一个星期的程序出现错误时,您可以修复该错误并节省一些计算时间。
与程序使用的完整内存大小相比,程序状态可能非常小。
您问道“是否可以将正在运行的Java程序转储到文件中,然后重新启动它。”——是的,但我不建议使用通用和自动化的解决方案,该解决方案必须将您的程序作为黑盒处理,而是建议您将程序的重要部分和程序重启点外部化。
希望这可以帮助您,即使它比您期望的更复杂。

1
让我们来看一下这种情况,即没有外部资源(文件、数据库、连接等)。 - ic3
如果这是一个现实世界的问题,你的应用程序是做什么的:是游戏、数字计算器还是模拟器? - Jörg Beyer
这是一个现实世界的问题,它是一个OLAP服务器(谷歌icCube)。 - ic3
那么我的草稿应该是适用的 - 但它不是一个通用的开箱即用解决方案,你只能将其应用于你的jvm。 - Jörg Beyer

7

我认为OP想要知道的是Smalltalk团队已经做了几十年的事情 - 将整个编程/执行环境存储在图像文件中,然后对其进行操作。

据我所知,在Java中没有办法做到同样的事情。


你可以用Smalltalk做到这个吗?有没有这个功能的名称,以便我可以在Google上搜索它? - Ajedi32
找一下如何保存Smalltalk的_image_,这样你就能走上正确的轨道了 ;) - Óscar López

7

有一些关于“持久化”JVM执行状态的研究,然后将其移动到另一个JVM并重新启动它。曾经看到过一些演示,但不记得是哪一个了。我认为它还没有在JVM规范中标准化...

找到了我想要的演示/展示,当时他们在OOPSLA 2005上讨论了 squawk

祝好运!

其他感兴趣的链接: Merpati

Aglets

M-JavaMPI


3

使用SpringBatch框架怎么样?

根据您的问题,我理解您需要一个可靠且可恢复的Java任务,如果是这样,我相信Spring Batch可以做到这一点,因为您可以将任务(job)拆分为多个步骤,而每个步骤(以及整个任务)都有自己的执行上下文,该上下文存储在您选择的存储器中。

如果发生崩溃,您可以通过分析特定作业的先前运行并从故障发生的确切位置恢复来进行恢复。

如果作业已配置为可重启且此作业的ExecutionContext已存在,则还可以通过编程方式暂停和重新启动作业

祝你好运!


3

我认为: 1- 唯一通用的方法是实现序列化。 2- 恢复运行系统的好方法是操作系统虚拟化。 3- 现在你正在询问类似单进程序列化的东西。

问题出在输入/输出。 如果你的进程使用一个临时文件,在“休眠”后被系统删除,但你的程序并不知道,那么就会在某个地方发生IOException。

所以说,如果程序没有设计成随时可中断,它就不能正常工作。 这是一种冒险而且难以维护的解决方案,因此我认为只有1、2才有意义。


2

我猜IDE支持这种调试方式。虽然我不知道具体如何实现,但并非不可能。如果您联系一些Eclipse或NetBeans的贡献者,可能会得到更多细节。


0
首先,您需要设计您的应用程序以使用Memento pattern或任何其他允许您保存应用程序状态的模式。观察者模式也可能是一种选择。一旦您的代码结构可以保存状态,您可以使用Java序列化将所有对象等实际写入文件而不是放入数据库。
只是我的两分钱。

0

从计算机架构的本质来看,你想要的是不可能的。

每个Java程序都会被编译成Java中间代码,然后在运行时被解释成本地平台代码。本地代码与Java文件中所见的代码非常不同,因为它取决于底层平台和JVM版本。每个平台都有不同的指令集、内存管理、驱动程序系统等等... 所以想象一下,如果你在Windows上休眠了你的程序,然后在Linux、Mac或任何其他带有JRE的设备上运行它,比如手机、汽车、读卡器等等... 一切都会失控。

你的解决方案是将每个重要对象序列化到文件中,然后优雅地关闭程序。当“取消休眠”时,你可以从这些文件中反序列化这些实例,使你的程序可以继续运行。重要实例的数量可能相当小,你只需要保存“业务数据”,其他所有内容都可以从这些数据中重建。你可以使用Hibernate或任何其他ORM框架,在SQL数据库的顶部自动执行此序列化。


问题不在于在一个操作系统中休眠,然后启动到另一个操作系统。 - ic3
我以为你要求将JVM的状态休眠。那个文件可以在任何其他计算机上传输。 - Jakub Zaverka
如果可能的话,这确实是非常好的。 - ic3

0

可能Terracotta可以做到这一点:http://www.terracotta.org

我不确定,但他们支持服务器故障。如果所有服务器停止,进程应该保存到磁盘并等待。

否则,您应该重构应用程序以显式地保留状态。例如,如果您实现了类似可运行的东西并使其可序列化,您将能够保存它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接