自发存储数据损坏(如位翻转)在正常 SDRAM(包括 DDR 1/2/3/4 SDRAM)操作中并不常见但仍然很有可能发生,这不是什么秘密。
服务器和重型工作站使用内置于其 SDRAM 模块的 ECC 机制来解决这个问题,保证读取的数据字始终是之前写入该特定地址的数据字。
但是对于使用非 ECC RAM 模块的台式机/笔记本电脑和手持设备来说怎么办呢?开发人员如何确保变量包含的正是写入的值?
答案1
我认为没有任何机制可以防止非 ECC 系统中的错误,无论是在系统级别还是在操作系统级别。我不相信 Windows 会定期刷新 RAM 内容,硬件应该将值保存在内存中。
启动系统时,BIOS 中会进行快速内存检查,因此可以在那里检测到一些主要错误。
有些文件(例如安装程序)可能会执行 CRC 校验。但这些错误可能来自存储介质而不是内存。
如果在不使用或将被覆盖的内存位置中发生随机错误。没问题。我怀疑很大比例的随机、非重复错误发生在该空间中。
应用程序空间中的损坏可能会产生异常而不是崩溃,这可能会或可能不会得到妥善处理。然而,这仅仅是运气——“内存错误”本身没有异常,但错误可能发生在恰好由异常处理程序处理的地方。否则,应用程序要么会携带损坏的数据,要么在导致无效操作时崩溃。
除此之外,应用程序/操作系统将崩溃并且写入的文件将损坏。
如果应用程序愿意,可以通过执行两次或多次操作来实现检查机制。内存检查器和第三方文件复制工具就是这样的例子。
答案2
是的,通常系统会在启动时执行 RAM 测试并尝试隔离任何坏页。
否则,如果在操作过程中以某种方式发现了坏页(在大多数消费类电脑上不太可能发生,因为它们通常没有奇偶校验,但在“大型机”上有可能发生),那么,如果该页面是“虚拟的”并且没有被标记为“已更改”,系统可能会“删除”该页面,将物理页面标记为坏页,然后从磁盘将其重新换页。
但是,如果页面是“脏的”(已更改),错误将作为某种异常报告给应用程序。如果坏页面是某种系统页面,则系统将崩溃。
当然,如果没有奇偶校验或其他机制来发现错误,坏数据就会被简单地使用,不管发生什么都会发生。这是消费硬件上最可能出现的情况。
答案3
它们根本无法处理这种情况。启动测试会处理内存的最后一位,而这也就是普通 BIOS 所做的一切。Linux/FreeBSD 等已修复,它们允许您排除内存地址,使其不被系统访问。除非您这样做,否则当内核内部完整性检查发现“位翻转”(Unix 中的信号 11)时,系统很可能会崩溃