保存进程的内存供以后使用?
Posted
技术标签:
【中文标题】保存进程的内存供以后使用?【英文标题】:Save a process' memory for later use? 【发布时间】:2010-10-17 07:21:15 【问题描述】:是否可以暂停进程,将内存内容保存到文件中,然后重新加载文件以便继续执行程序?
编辑 我一直在读这个:
http://en.wikipedia.org/wiki/Setcontext
是否可以转储结构的内容,并以某种方式强制 malloc 分配相同的内存区域?
【问题讨论】:
cryopid 允许在不修改 linux 内核的情况下这样做。 【参考方案1】:技术上这是可能的,但它也需要保存所有系统分配的资源状态 - 例如文件描述符,然后恢复它们。所以这是一项具有挑战性的任务。
实现您想要的最简单的方法是使用像 VMWare 这样的虚拟机。当你暂停它时,你实际上保存了整个机器状态以及所有正在运行的程序。
【讨论】:
VMWare 会确保网络接口等其他资源正确重启。 这不仅具有挑战性,而且在一般情况下是不可能的。见blogs.msdn.com/oldnewthing/archive/2004/04/20/116749.aspx @GSerg,该链接假定进程外的资源将在休眠时释放。在进程只是隐藏在不运行队列中并且它的地址空间发送到磁盘而不放弃外部进程资源的情况下,情况不一定是这样。 我可以将其设想为对 UNIX SIGSTOP/SIGCONT 的简单扩展 - 它现在不会放弃这些资源,并且可以将其更改为将整个地址空间交换到磁盘。机器重启无法幸免,但您可以达到预期的效果。 这种效果可以随意停止和启动进程。当然,您会遇到在进程停止时资源被锁定的问题,但您可以有工具告诉您(然后您将重新启动进程以释放它)。【参考方案2】:这通常称为persistent continuation。一些语言,如 SmallTalk 和 SBCL,对持久延续具有一流的支持。大多数语言都没有。
【讨论】:
Continuations 构成程序内部的控制流,它们不会停止或启动程序执行。 @sth 一些 Smalltalk 运行时和 SBCL 支持持久的延续,而不仅仅是你所想的瞬时延续。【参考方案3】:引自“Persist (hibernate!) a process state to disk for quiker loading”(原文如此):
问。您能否详细解释一下这种交换是如何工作的,以便将进程状态保存在磁盘中并在需要时重复使用?”
A.这很简单。页面文件是磁盘上的一个特殊位置 非活动进程以高度优化的方式存储。当这样 进程恢复运行,系统自动将其读回 记忆,它只是从原来的地方继续。这有点像 程序在 iPad 上运行 :)
所有这些功能都已内置在 Windows 中。当你的 进程保持运行,系统确保它处于 内存或页面文件中(尽管有很少的例外,你 可以忽略)。
换句话说,Windows 已经能够将进程休眠到页面文件。 @MSalters 引用 Raymond Chen 的“explaining why its impossible”是完全错误的。
【讨论】:
请注意,换出进程的簿记仍然存在于 RAM(内核)中。它的窗口句柄仍然有效;您可以向它发送消息,使其返回页面等。这就是为什么这通常不被视为进程休眠。【参考方案4】:Raymond Chen explains 为什么不可能。显然,并非所有 Microsoft 工程师都阅读此内容,因为 Visual Studio 编译器在预编译头文件时会这样做。它在第一次编译头文件后转储自己的状态,并恢复自己继续。
【讨论】:
陈先生是对是错。如果外部进程资源消失,这只是不可能的。这不必发生。您可以在保留进程外资源的同时完全停止进程 - 显然这不会在重新启动后继续存在,但这不一定是这里需要的。 在您执行一些 CPU 密集型工作时完全停止进程一小时的能力仍然很有价值。然后,您只需重新启动该过程。 SIGSTOP/SIGCONT 已经在 UNIX 等平台上执行此操作。 实际上,将优先级降低到空闲就足够了。使用最后一个核心的最后百分之几没有害处,许多并行算法无法在整个操作中维持完全并行性 - 特别是对于树。 Raymond Chen 试图解释为什么这是不可能的,但 Cooney 驳斥了他的所有论点。【参考方案5】:根据您的要求和操作系统,您可以尝试强制core dump
除了在 gdb 中之外,我从未尝试过实际加载核心转储程序备份。正如Sharptooth指出的那样,您打开的任何文件或不在程序内存中的任何其他状态似乎都会丢失。
另一种方法是简单地序列化您需要在程序中存储的状态。这很糟糕,但它可能是最可靠的方法,除非您满足于暂停程序的执行。这可以通过您的操作系统的线程库来完成。或者正如一张海报用你的外壳指出的那样。
【讨论】:
【参考方案6】:正如sharptooth 所提到的,在处理本机代码时,它混乱到了不可能的地步。
但是,一些程序(例如 iirc emacs)使用“转储我自己的内存”技巧来保存配置,而不是处理配置文件。但是,这在 Windows 上不起作用,因为可执行文件在拒绝写入共享模式下运行。但这是在 linux 或 DOS 上的一个可爱(尽管很危险)的把戏 :)
【讨论】:
【参考方案7】:好吧,java 有序列化,它就在它附近的某个地方。尽管您不能将其执行到最低级别,例如 CPU 寄存器内存地址等,因为这将要求 os 处于与“暂停”进程时相同的状态。
这可能是一个作为 linux 内核模块的好项目 :-)
【讨论】:
【参考方案8】:.NET 3.0 及更高版本中的 Workflow Foundation 允许停止和重新启动工作流。
【讨论】:
以上是关于保存进程的内存供以后使用?的主要内容,如果未能解决你的问题,请参考以下文章