Omar Elrefaei Asked: 2018-04-23 08:48:42 +0800 CST2018-04-23 08:48:42 +0800 CST 2018-04-23 08:48:42 +0800 CST 是否可以将程序的内存转储到文件并再次恢复? 772 我想将某个程序使用的 RAM 复制到文件中。然后稍后再次恢复该状态。 类似于 ctrl+z & fg 的效果,但我也想从该程序中释放 RAM。 core-dump memory 4 个回答 Voted Best Answer Basile Starynkevitch 2018-04-23T08:53:42+08:002018-04-23T08:53:42+08:00 我想将某个程序使用的 RAM 复制到文件中。然后稍后再次恢复该状态。 误解:一个进程有它的虚拟地址空间并使用虚拟内存。RAM 本身是由操作系统内核管理的资源。读取操作系统:三个简单的部分(一个进程不直接使用RAM)。 (你最好编辑和改进你的问题,以便更多地解释它:你有什么样的程序,在什么情况下,为什么,你需要“停止”程序多长时间,你呢?需要稍后重新启动它的改进版本...?没有这些细节,我们无能为力。) 在 Linux 上,您可以使用proc(5)来查询某个给定进程的虚拟地址空间。尝试cat /proc/$$/maps并cat /proc/self/maps 我也想释放内存 不需要这样做,因为内核正在管理 RAM(有时可能会发生抖动)。另请参见madvise(2)、posix_fadvise(2)、mmap(2)、mlock(2)。当一个进程终止时,内核将释放它的虚拟地址空间,然后重新使用分配给它的 RAM。当一个进程停止时(例如通过Ctrl Z发送SIGTSTP,参见signal(7)和termios(3)),内核可能会将其 RAM 用于其他目的(并使用交换空间来存储该停止进程的脏页 - 即页面输出)。阅读需求分页和http://linuxatemyram.com/ 您想要的与应用程序检查点和正交持久性有关。在 Unix 和 Linux(以及大多数其他操作系统,包括 Windows、Android、MacOSX ......)上,一般来说这是不可能或非常困难的(你将如何处理打开的文件描述符、子进程、套接字、ASLR、信号量、线程、文件 锁定,图形 用户 界面,共享 库, ETC...)。但是你可以编写一个具有这种特性的应用程序(你可以找到帮助的库);当然,您将遵循一些额外的约定和限制,以使持久性或检查点变得可行和实用。 如果您想要整个系统,请考虑hibernation。 持久性是在应用程序设计时很早就要考虑的事情(之后可能很难添加)。请注意,数据库(sqlite、RDBMS、nosql数据库...)和索引文件(gdbm ...)可以被视为实现某种持久性的常用方法(您可以将堆视为对象的循环图) . 持久化与代码相关的数据(例如类、vtables、闭包、函数指针......)通常很难。 您可以找到一些用于检查点的库,例如BLCR或CRIU。当然,它们在为使用它们而开发的应用程序的有限上下文中工作。 最后,从算法的角度来看,持久化整个状态(或检查点)非常接近于复制精确的垃圾收集器。所以阅读一些关于它们的东西,例如GC 手册,是很有用的。 但是,真正的持久性或检查点很难实现,应该在应用程序设计的早期就实现。在许多情况下,要求完全重写不提供它的应用程序已经够难的了。 与代码的演变保持兼容更加困难(例如,能够使用应用到旧检查点的较新版本的代码重新启动)。您可能会受到动态软件更新技术的启发。 一些编程语言实现(例如 Ocaml、Python、Java 等)提供了可以提供帮助的序列化或编组工具。其他人有一些检查点的方式(例如 SBCL save-lisp-and-die,PolyML export)。同音性和反射是有用的编程语言特性。 另请参阅RefPerSys和Bismon作为持久系统的示例。 dirkt 2018-04-23T08:57:50+08:002018-04-23T08:57:50+08:00 类似于 ctrl+z & fg 的效果,但我也想从该程序中释放 RAM。 Ctrl-zfg会做你想做的事:当内核需要 RAM 时,它会将被挂起的程序用于磁盘的 RAM 写入交换分区,这样它就可以将 RAM 重新用于其他用途。稍后激活程序时fg,它将从交换中读取该 RAM。 Andrew Reid 2018-04-25T03:44:09+08:002018-04-25T03:44:09+08:00 可能有一些兴趣,文档生成程序 TeX 和 LaTeX 的早期版本使用工具构建它们的变体,这些工具将启动基本程序,加载所需的所有各种模块,然后触发核心转储,并构建新的“预配置”可执行文件从核心转储。 在 tex.stackexchange 上有一些很好的讨论。 我认为即使在那天它被认为是一种奇怪的方式,它只真正影响了运行时预链接的一种形式,它并没有保留运行过程的状态(动态变量值等)。全部。 显然,emacs 的早期版本也这样做了,我不知道。 skyking 2018-04-25T00:59:18+08:002018-04-25T00:59:18+08:00 除了 Ctrl+Z & fg 之外,您不太可能做您想做的事。 问题是虽然可以将进程的内存保存到文件中(例如生成核心转储),但您似乎旨在能够从内核的进程表中删除该进程。但是这样做时,您将释放进程持有的所有其他操作系统资源,例如打开的文件等。 通常在创建这些资源时,不会存储它们的获取方法——这意味着没有任何地方存储有关如何重新获取资源的信息。即使该信息保存在某处,也不能保证以后重新获取它们是可能的(成功获取可能取决于过程外部的状态,甚至可能取决于可能已更改的计算机)。
误解:一个进程有它的虚拟地址空间并使用虚拟内存。RAM 本身是由操作系统内核管理的资源。读取操作系统:三个简单的部分(一个进程不直接使用RAM)。
(你最好编辑和改进你的问题,以便更多地解释它:你有什么样的程序,在什么情况下,为什么,你需要“停止”程序多长时间,你呢?需要稍后重新启动它的改进版本...?没有这些细节,我们无能为力。)
在 Linux 上,您可以使用proc(5)来查询某个给定进程的虚拟地址空间。尝试
cat /proc/$$/maps
并cat /proc/self/maps
不需要这样做,因为内核正在管理 RAM(有时可能会发生抖动)。另请参见madvise(2)、posix_fadvise(2)、mmap(2)、mlock(2)。当一个进程终止时,内核将释放它的虚拟地址空间,然后重新使用分配给它的 RAM。当一个进程停止时(例如通过Ctrl Z发送
SIGTSTP
,参见signal(7)和termios(3)),内核可能会将其 RAM 用于其他目的(并使用交换空间来存储该停止进程的脏页 - 即页面输出)。阅读需求分页和http://linuxatemyram.com/您想要的与应用程序检查点和正交持久性有关。在 Unix 和 Linux(以及大多数其他操作系统,包括 Windows、Android、MacOSX ......)上,一般来说这是不可能或非常困难的(你将如何处理打开的文件描述符、子进程、套接字、ASLR、信号量、线程、文件 锁定,图形 用户 界面,共享 库, ETC...)。但是你可以编写一个具有这种特性的应用程序(你可以找到帮助的库);当然,您将遵循一些额外的约定和限制,以使持久性或检查点变得可行和实用。
如果您想要整个系统,请考虑hibernation。
持久性是在应用程序设计时很早就要考虑的事情(之后可能很难添加)。请注意,数据库(sqlite、RDBMS、nosql数据库...)和索引文件(gdbm ...)可以被视为实现某种持久性的常用方法(您可以将堆视为对象的循环图) . 持久化与代码相关的数据(例如类、vtables、闭包、函数指针......)通常很难。
您可以找到一些用于检查点的库,例如BLCR或CRIU。当然,它们在为使用它们而开发的应用程序的有限上下文中工作。
最后,从算法的角度来看,持久化整个状态(或检查点)非常接近于复制精确的垃圾收集器。所以阅读一些关于它们的东西,例如GC 手册,是很有用的。
但是,真正的持久性或检查点很难实现,应该在应用程序设计的早期就实现。在许多情况下,要求完全重写不提供它的应用程序已经够难的了。
与代码的演变保持兼容更加困难(例如,能够使用应用到旧检查点的较新版本的代码重新启动)。您可能会受到动态软件更新技术的启发。
一些编程语言实现(例如 Ocaml、Python、Java 等)提供了可以提供帮助的序列化或编组工具。其他人有一些检查点的方式(例如 SBCL
save-lisp-and-die
,PolyMLexport
)。同音性和反射是有用的编程语言特性。另请参阅RefPerSys和Bismon作为持久系统的示例。
Ctrl-z
fg
会做你想做的事:当内核需要 RAM 时,它会将被挂起的程序用于磁盘的 RAM 写入交换分区,这样它就可以将 RAM 重新用于其他用途。稍后激活程序时fg
,它将从交换中读取该 RAM。可能有一些兴趣,文档生成程序 TeX 和 LaTeX 的早期版本使用工具构建它们的变体,这些工具将启动基本程序,加载所需的所有各种模块,然后触发核心转储,并构建新的“预配置”可执行文件从核心转储。
在 tex.stackexchange 上有一些很好的讨论。
我认为即使在那天它被认为是一种奇怪的方式,它只真正影响了运行时预链接的一种形式,它并没有保留运行过程的状态(动态变量值等)。全部。
显然,emacs 的早期版本也这样做了,我不知道。
除了 Ctrl+Z & fg 之外,您不太可能做您想做的事。
问题是虽然可以将进程的内存保存到文件中(例如生成核心转储),但您似乎旨在能够从内核的进程表中删除该进程。但是这样做时,您将释放进程持有的所有其他操作系统资源,例如打开的文件等。
通常在创建这些资源时,不会存储它们的获取方法——这意味着没有任何地方存储有关如何重新获取资源的信息。即使该信息保存在某处,也不能保证以后重新获取它们是可能的(成功获取可能取决于过程外部的状态,甚至可能取决于可能已更改的计算机)。