内存不足的情况下运行Windows


25

是否可以在RAM模块出现故障的情况下运行Windows(7,x64)?更准确地说,是否有某种方法可以告诉Windows不要分配已知的错误地址或地址块?

对于Linux,有BadRAM。Windows是否有现有的实现?Windows内核(NT 6.1)甚至可以实现吗?也许是内核模式驱动程序?


4
@ekaj如果购买后仅一周,可以在保修期内更换它吗?;)
Bob

3
实际上,那是最聪明的主意,它被打破了,让他们来解决它
Journeyman Geek

Answers:


15

鲍勃,您的问题分为三个部分。我一次给一个。

运行Windows时内存不足

确实有可能在模块损坏的情况下运行Windows 7。根据损坏扇区的位置以及模块在DIMM内存中的位置,只要不尝试触摸内存的损坏部分,Windows 7就会像没有任何东西一样运行。因此,理想情况下,应将有故障的模块尽可能地远离bank0。自然,如果这是您唯一的模块,那么您就不走运了。

在Windows中阻止坏的内存扇区

在x86(32位和64位)操作系统上,内存由内核管理。如您所述,BadMem能够阻止Linux中的坏内存扇区。它通过指示内核锁定您指定的那些内存地址来工作。这有效地阻止了Linux在分配(和取消分配)内存时访问这些地址。但是,为此,BadMem需要修补内核。BadMem仅仅是您在应用之前配置的内核补丁。

现在,您在Windows上没有该功能。您无法修补内核。开发内核模式驱动程序也不会带来任何好处,因为Windows内核永远不会让您的驱动程序优先于其内存管理体系结构(这是可以理解的)。

因此,您不能以任何方式指示窗口不使用某些内存地址。唯一的方法是Microsoft为您的案例专门修补内核。不太可能。

不良内存地址的扩散

内存模块可能包含错误地址的原因并不多。最终,所有这些归结为生产线中的错误,前提是假定它在进入计算机之前没有遭受损坏。众所周知,与硬盘驱动器相反,内存模块中没有活动部件。因此,不良扇区不会像硬盘扇区那样容易扩散。

但是,内存测试软件并非万无一失。它有可能(而且很常见)传递实际上是错误的某些地址。因此,随着越来越多的地址显示不正确,错误的内存可能会给人“传播”的印象。因此,诸如BadMem之类的工具会显示出它们的弱点,因为它们自然只能处理您指示它们的地址。

任何人都不可能对存储模块进行全面测试并识别所有不良的存储器地址,然后锁定它们并最终得到一个“良好”的存储模块。最简单的方法是将地址错误的模块视为有缺陷的模块,因此始终不被信任。

这意味着,尽管BadMem是一个有吸引力的主张,但它实际上并不是解决内存不足问题的解决方案。更有可能的是,您仍然会遇到尝试读取坏扇区并因停止错误而崩溃的操作系统。坏模块是坏模块,是坏模块。


有不少很好的答案,但我会接受这给了一个很好的理由,为什么不这样做。就像其他人指出的那样,可以告诉Windows内核不要使用某个特定的地址,但是当错误位于地址空间的中间时,就好像您要使用scapel时使用斧子一样……需要更精细的控制,但是,显然,这是不可能的。真遗憾。
鲍勃2012年

8
不太正确;它能够指示Windows,以避免某些地址(更准确地,某些页面帧号)。该功能是为ECC内存设计的,Windows可以使用它检测可能的故障并将这些PFN标记为不良,但是可以手动将PFN添加到列表中:superuser.com/a/490522/117590-不太实用。所以,是的,更换仍然是最好的选择:P
鲍勃

17

Windows BCD(引导配置数据)实际上有一个{badmemory}对象。似乎ECC内存“预计将失败”的内存地址将在此处列出,而不被操作系统使用。

{badmemory}对象接受一个BadMemoryList(BCD type 0x1700000a)元素,该元素是可以用十六进制输入的整数列表,以空格分隔。我想可以手动将memtest86发现的坏内存地址插入到此元素中-但我尚未对此进行测试。显然,它接受“页帧号”,即实际地址除以4096。不幸的是,这些地址/ PFN可能与内存诊断报告的地址/ PFN不匹配。可以使用Visual BCD Editor进行手动编辑。

在任何情况下,都应按照其他答案所示更换故障的记忆棒。这仅仅是解决此问题的一种方法(暂时?)。


您可以在此处找到有关您所说的一切的格式更好的教程。不错,尽管如此。
mirh,2017年

13

Windows BCD具有{badmemorylist}{badmemoryaccess}对象。您应将第一个设置为以空格(例如bcdedit /set badmemorylist 1499543 1434007)分隔的错误内存页面,第二个设置为Nobcdedit /set badmemoryaccess No

请记住,通常Windows中的内存页面大小 4KB

在Windows 7中进行了测试,效果很好

您可以通过Sysinternals的Rammap测试设置

PS我有从 "Windows Internals Book" chapter 10


13

我在使用SoC的平板电脑中遇到内存问题。内存已焊接或集成到SoC中,无法更换。

我在阿根廷,卖家在中国,运费和时间都没有保证意义。

我设法了一些命中。

传递损坏的内存参数的关键是:

  1. memtest86中的地址与Windows中使用的地址匹配。
  2. 必须标记4 KB的整页。
  3. 在memtest中0x10000000对应于Windows中的0x10000
  4. 在memtest中0x00001000对应于Windows中的0x1
  5. 表示:Windows中的页码删除了最后3个memtest十六进制数字。
  6. 表示:窗口消除了左侧的零。
  7. 考虑5和6,以避免页码中的错误。
  8. 正确的语句是:bcdedit /set {badmemory} badmemorylist 0xB7 0xB8 0xB9 0xBAmemtest中的错误从0x000B7000到0x000BAFFF。请注意,您不能放置一系列记忆,但是所有页面都一个接一个
  9. 无法添加页面,应在同一命令中标记所有页面。如果是新页面,则添加将覆盖较旧的页面。我设法在一个命令中添加了4096页。我没有尝试更多。
  10. bcdedit /enum {badmemory},显示已标记页面的列表。
  11. bcdedit /set badmemoryaccess no 防止使用标记的页面
  12. 标记页面后需要重新启动并删除访问权限。

1
我必须删除/和命令之间的空白才能使它工作,所以对于其他命令来说,空白bcdedit / enum {badmemory}将是bcdedit /enum {badmemory}相同的
flagg19

它可以工作,但是不幸的是,Windows上的cmd限制限制为8191,并且我无法阻止所有错误的内存页面。我找不到解决此问题的好方法。有没有办法记录页面范围?我应该阻止从0x714bc8到0x71cbd0的所有页面,页面太多了!我做了什么,所以?我进行了最简单的测试(#0和#1),但是它的内存错误范围更有限。到目前为止,它运行良好,不再显示蓝屏。但是我知道我并没有阻止所有必要的事情。
费利佩

3

据我所知,唯一的方法是使用BurnMem命令,该命令可以人为限制RAM窗口的使用量。


2
嗯..这是一个有趣的选择。也许maxmem,因为显然burnmem并没有限制最大物理地址maxmem。Vista和7等效truncatememory。尽管这是一个可能的解决方案,但是对于有缺陷的存储器位于地址空间的中间或开头并在不需要之后阻塞所有内容的情况,是否有一种更精确的方法?
鲍勃2012年

@Bob-您不能简单地替换不良记忆模态的原因是为什么?
拉姆猎犬,2012年

如果可以的话,我可以@Ramhound。但这需要时间。现在,我的原始内存已用完一半,对我的VM来说不是很好。获取一个新的或替换的模块,可能会花费数周的时间。如果软件解决方案可以让我在两个小时或更短的时间内完成此操作,那么我会认为它花了很多时间,并且学到了一些新知识。我会接受这个答案(我的记忆恰巧在地址空间的末尾失败了),但是如果有人有一个更通用的解决方案,我希望以后再参考。
鲍勃

@Bob-刚刚广泛地阅读了这篇文章,看来这是不可能的。这是因为BadRam利用memtest来指示内核从引导加载程序中排除错误地址,Windows无法执行此操作,因为目前尚无办法以与BadRam修补内核可以排除的相同方式来确定要排除哪些错误地址。 。
奥利弗·G


2

警告!!!Windows可能无法启动,请准备重建BCD。在这种情况下,请使用“高级启动选项”中的“命令提示符”。我不知道为什么它不会再启动,似乎是随机发生的,或者如果您将太多地址输入到badmemorylist中。

bootrec /rebuild bcd
bcdedit /export c:\bcdbackup
attrib c:\boot\bcd -h -r -s
ren c:\boot\bcd bcd.old
bootrec /rebuild bcd

继承人C ++命令提示符PROGRAMM是得到一个连续的内存ADRESS列表中的.txt文件准备bcdedit /set badmemorylistbcdedit /set {badmemory} badmemorylist(没有工作Win7上对我来说)

使用bcdedit /set badmemoryaccess 0拒绝访问。

您可以在视图设置->详细中使用EasyBCD进行检查。重新启动后,使用Rammap检查物理地址空间是否消失。

#include <cstdlib>
#include <iostream>
#include <fstream>

//converts hex into base10
unsigned long convertHexToIntBase10(char* inputHex)
{
    unsigned long hexValue = std::strtoul(inputHex, 0, 16);
    return hexValue;
}

int main(int argc, char* argv[])
{
    if(argc < 3){
        std::cerr << "Usage: MemoryPageListHex [Low Memory Adress] [High Memory Adress] in 4k Pages i.e. MemoryPageListHex 1bae50 1bb0e7 for 0x1bae50148 to 0x1bb0e7fe8" << std::endl;
        return 0;
    }
    auto lowAdr = convertHexToIntBase10(argv[1]);
    auto highAdr = convertHexToIntBase10(argv[2]);
    std::ofstream myfile;
    myfile.open ("MemoryAdress4k.txt");
    for (auto i=lowAdr; i<highAdr; i++){
        myfile << std::hex << "0x" << i << " ";
    }
    myfile.close();
    return 0;
}

1

是。有启动参数可以控制Windows可以使用的内存量。但是,您只能从内存空间的末尾删除。请参阅此msdn文章以控制启动参数。感兴趣的参数是truncatememoryremovememory


截断并删除内存似乎只是切断RAM访问(从给定的阈值开始,或从末尾开始向后工作)。这个问题更多地是关于提供范围。
mirh,2017年

0

您可以在Windows 7中尝试此功能,但是我不确定它会影响哪个芯片,或者每个功能是否削去了相同的数量。我必须环顾四周才能找到答案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.