出于好奇,我正在寻找关于“windows hibernate选项如何工作”的文章/文档,即当在Windows关闭对话框中选择“Hibernate”选项时。我从一些消息来源得到的答复是,它仅仅是内存和寄存器的序列化。
如果我错在这里,请原谅我。如果windows可以序列化任何应用程序,进程或对象,无论其是可序列化的还是非可序列化的,那么.NET如何将可序列化对象限制为具有[Serializable]属性或ISerializable接口的对象?答案 0 :(得分:6)
在进程地址空间内,一切都只是字节;一些堆栈,一些托管堆等。字节固有可序列化 - 它们只是字节。所有hibernate都必须暂停线程并将整个地址空间写入磁盘。
使用对象,您希望将它们保存到某些内存不足的结构中。不幸的是,它使毫无意义存储地址等,因为它异常不可能在内存中完全相同的点水化。此外,许多事情,如非托管对象句柄在重新水合时没有任何意义。您也很可能只想保存小对象块,而不是整个进程空间。即使在一个小图表中,这些对象也可以分散在遍布的地方 - 所以你不能只复制几页内存。
还要记住,序列化的一个常见用途是深度克隆对象;如果你依赖于对象的内存中表示,你必须反序列化到内存中完全相同的位置 - 所以你不能克隆任何。那就是之前你接触到诸如压缩垃圾收集器之类的概念,这些概念会在你不看的时候在内存中移动物体。
还要考虑您可能正在将数据加载到不同的平台/体系结构中,或者想要编写特定的格式(xml,json等)。
因此,序列化代码不是仅仅复制原始内存,而是必须查看单个对象,遍历引用并以允许从根本没有的源进行再水化的方式编写对象图。原始记忆。更难。
答案 1 :(得分:2)
这是两件非常不同的事情。 Windows可以在任何给定时间控制内存中的内容,并可以直接访问硬件。 “序列化”是一个用来描述它支持休眠的方法,但我认为它与CLR中的概念不同。
在.NET中,序列化是一种通常由开发人员发起的显式操作;该属性告诉框架您标记有它的类型可以流出并重新输入,而不必担心状态或行为的变化。
从技术上讲,CLR可以序列化我想要的任何东西,毕竟它可以访问每种类型的底层表示,并跟踪每个对象实例。所以我猜你可以在任何给定点“休眠”整个应用领域;这将更接近Windows的作用。
答案 2 :(得分:1)
,仅仅是内存和寄存器的序列化
“序列化”可能是错误的术语;无论谁告诉你,这可能仅仅意味着“复制”。
让我们来看看这两个概念是如何不同的。
基本上,序列化意味着将对象转换为连续字节的流,并且以后可以从该流精确地重建它。为什么我强调“连续”?原因如下:如果一个对象引用另一个位于另一个内存位置的对象(即,不与被序列化的对象“相邻”),那么序列化也会将该另一个对象带入字节流,因此没有依赖关系特定内存位置的对象。最终得到一个可能包含完整对象图的单字节数组,而不再对外部对象进行任何引用。
现在,休眠可能不需要这一切。您只需将其全部复制到硬盘(无需任何修改或重新排序)即可创建计算机RAM,CPU寄存器和I / O寄存器的完整快照。 (稍微聪明的休眠过程可能只包括操作系统实际分配的内存,即只有正在使用的内存。)
但是我敢说休眠比这稍微复杂一些:例如,当涉及到I / O寄存器时,你很快就不能复制保存的寄存器值;您可能还必须注意以正确的顺序编写I / O寄存器,以使某些I / O设备恢复到先前的状态。我可以想象PCI / AGP标准对节能状态有特殊处理,这样您就可以通过专用I / O寄存器向设备询问其当前状态的快照。 (但这只是猜测。)