出于好奇,我在寻找一篇关于“Windows休眠选项如何工作”的文章/文档,即当用户在Windows关闭对话框中选择“休眠”选项时。一些来源给出的回答是,它仅仅是内存和寄存器的序列化。 如果我理解有误,请谅解。如果Windows可以序列化任何应用程序、进程或对象,无论它们是否可序列化,为什么.NET限制可序列化对象只能具有[Serializable]属性或ISerializable接口呢?
在进程地址空间中,一切都是字节;一些堆栈,一些托管堆等。字节本质上是可序列化的 - 它们只是字节。因此,所有的休眠操作都需要做的就是暂停线程并将整个地址空间写入磁盘。在处理对象方面,您需要将它们保存到一些非内存结构中。不幸的是,存储地址等毫无意义,因为很难通过反序列化恢复到完全相同的内存位置。此外,许多像非托管对象句柄这样的东西在重新加载时也毫无意义。另外,通常情况下,您可能只想保存一个小块的对象,而不是整个进程空间。即使在一个小的图形中,这些对象也可能分散在各处,所以您不能只复制几页内存。还要注意,序列化的常见用途是对对象进行深度克隆;如果依赖于内存中对象的表示,则必须将其反序列化到完全相同的内存位置 - 因此您无法克隆任何东西。这还没有触及诸如压缩垃圾收集器之类的概念,其可以在您没有看到时移动对象。还要考虑到您可能将数据加载到不同的平台/架构中,或者想要编写特定格式(xml、json等)。因此,序列化代码必须查看各个对象,遍历引用,并以允许从与原始内存完全无关的源重新启动的方式编写对象图形。这更加困难。
这是两个非常不同的东西。Windows随时控制内存中的内容,并直接访问硬件。我想“序列化”是描述它支持休眠的一个词,但这并不是CLR中的概念。在.NET中,序列化通常由开发人员显式操作。该属性告诉框架,标记有该属性的类型可以流式传输而无需担心状态或行为差异。从技术上讲,CLR可能会序列化任何东西,毕竟它可以访问每种类型的底层表示,并跟踪每个对象实例。因此,我想你可以在任何给定点“休眠”整个应用程序域;这更接近于Windows所做的事情。
[Serializable]
或ISerializable
; 其他二进制序列化器有不同的要求。但在许多情况下(例如文件句柄),将其序列化没有意义。它无法自行重新创建文件句柄。 - Marc Gravell