【问题标题】:How can I simulate a low memory condition in Windows 7如何在 Windows 7 中模拟内存不足的情况
【发布时间】:2011-12-11 06:42:39
【问题描述】:

我有一个用 C# 编写的应用程序运行良好,但偶尔会在现场出现错误,我们认为这是由于内存不足或与垃圾收集器交互造成的。

如果有人有兴趣,在这里描述:
Unable to cast object of type 'NHibernate.Impl.ExpandedQueryExpression' to type 'NHibernate.Linq.NhLinqExpression'

我想尝试重现这个以进行调试,但是我的开发机器内存太多。

我已删除页面文件,因此我的虚拟内存仅限于 12GB 的物理内存,因此除了物理删除 ram 之外,是否有人对如何在开发环境中模拟低内存条件有任何建议?

编辑:
删除了关于监控垃圾收集器的工具的询问?

【问题讨论】:

  • 您似乎认为您的机器拥有硬件内存与进程拥有虚拟内存有关。 几十年来并非如此。请记住,物理内存虚拟内存地址空间几乎没有任何关系。无论您拥有多少物理内存,该进程都会获得相同数量的虚拟内存;更多的物理内存只会使使用虚拟内存更快您想模拟虚拟内存地址空间不足还是物理内存不足
  • 是的,有 很多 工具可以监控垃圾收集器。给自己找一个内存分析器,或者观察性能计数器。
  • @Eric,你是对的,我应该更清楚。在尝试调试时,我删除了页面文件,因此我的虚拟内存被限制为 12GB 的物理内存。
  • 究竟是什么原因让您相信内存不足会导致无效的强制转换异常?我发现像这样的随机问题可能更多地归因于线程安全问题,在这种特殊情况下,NHibernate 库中的某些代码可能无法在高负载情况下表现良好。我当然不会得出这样的结论,即可用的虚拟地址空间甚至机器的物理 RAM 量与无效转换异常有任何关系。
  • 我注意到现在你仍然可能没有模拟你想要模拟的东西;请记住,没有能力将虚拟内存提交到存储,因为没有存储,即使有足够的地址空间没有能力提交虚拟内存到存储因为没有地址空间可以映射它。 但更重要的问题是:为什么您认为您的问题与内存不足有任何关系?为什么一个无效的强制转换异常会让你相信这是一个内存问题,而不是类型错误?

标签: c# memory-management windows-7 garbage-collection


【解决方案1】:

您可以使用虚拟机(VPC、VMWare 或 Virtual Box)并调低内存。

这比错误更可靠。

编辑

此建议是一种模拟具有较少物理内存的 PC 的方法。如 cmets 和其他答案中所述,如果您希望调低虚拟内存“吃掉”进程开始时的堆将是一个解决方案。

【讨论】:

    【解决方案2】:

    您拥有的 RAM 量与 Windows 等虚拟内存操作系统无关。没有足够的东西只会减慢程序的速度。重要的是虚拟内存地址空间的大小,在 32 位操作系统上为 2 GB。如果您有 64 位操作系统,请将 EXE 项目上的目标平台设置为 x86。

    您可以通过在程序开始时调用 Marshal.AllocHGlobal() 来任意增加内存压力。分配一块,比如说,500 兆字节。不多,那很容易失败。通过分配 90 MB 块来获取更多。

    【讨论】:

    • 你是对的,我应该更清楚。在尝试调试时,我删除了页面文件,因此我的虚拟内存限制为 12GB 的物理内存
    【解决方案3】:

    不是答案,而是我在 The Code Project - Memory Allocation Tool 找到的一个非常酷的实用程序

    简介

    有时在极端情况下测试您的应用程序非常有帮助,例如
    资源不足、硬盘已满或内存不足。

    此工具仅涵盖最后一个 - 内存。
    它允许您分配尽可能多的可用内存。

    【讨论】:

    • 最多分配 2GB,因此对 64 位机器没有帮助。
    【解决方案4】:
    【解决方案5】:

    【讨论】:

    • 因为它不一定是可重复的,因此不可靠?因为这个错误明天可能会修复?
    • 他问了一个解决方案,这个还没有解决。这行得通。他没有问“永久调试方法”。
    【解决方案6】:

    要监控垃圾收集器的活动和进程内存使用情况,您可以使用 Windows 性能计数器。

    为什么不从 c# 程序中分配一个相当大的数组来填满你的 RAM?

    【讨论】:

    • 因为我认为是GC引起的,而不是内存本身
    【解决方案7】:

    您可以使用简单的 C 程序在堆上分配或尝试分配任意数量的内存:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MB (1024*1024)
    #define DEFAULT_ALLOC ((size_t) (512*MB));
    
    int main(int argc, char *argv[]) {
        char buffer[2];
        char *chunk;
        char *endp;
        size_t howmuch;
    
        if ( argc < 2 ) {
            howmuch = DEFAULT_ALLOC;
        }
        else {
            howmuch = strtoul(argv[1], &endp, 10);
            if ( *endp ) {
                fputs("Failed to parse command line argument", stderr);
                howmuch = DEFAULT_ALLOC;
            }
            else {
                howmuch *= MB;
            }
        }
    
        chunk = calloc(howmuch, 1);
    
        if ( chunk == NULL ) {
            fputs("Memory allocation error", stderr);
            exit(EXIT_FAILURE);
        }
    
        puts("Memory allocated.\nPress ENTER to terminate program");
    
        fgets(buffer, 2, stdin);
    
        return EXIT_SUCCESS;
    }
    

    【讨论】:

    • 这将消耗此进程的(虚拟)内存,而不是 .NET 应用程序进程的内存
    【解决方案8】:

    这是一个非常简单的程序,我们用它来测试我们的 linux 服务器上的低内存条件。我从未在 Windows 上编译过它,但它应该可以工作。

    https://github.com/julman99/eatmemory

    希望对你有用

    【讨论】:

      【解决方案9】:

      找到这个现在是 FreeWare 的实用程序:http://www.soft.tahionic.com/download-memalloc/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-22
        • 2012-06-10
        • 1970-01-01
        • 2011-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多