【问题标题】:Limiting the size of the managed heap in a C# application限制 C# 应用程序中托管堆的大小
【发布时间】:2010-12-10 18:44:52
【问题描述】:

我能否配置我的 C# 应用程序以将其内存消耗限制为 200MB? IOW,我不想等待自动 GC(这似乎允许堆增长得比这个应用程序实际需要的多得多)。

我知道在 Java 中有一个命令行开关可以传递给实现此目的的 JVM。在 C# 中是否有等价物?

附言

我知道我可以从代码中调用 GC,但我不想定期这样做。我宁愿在启动时设置一次然后忘记它。

【问题讨论】:

  • 您是否有特殊原因需要这样做?在人为限制内存环境中运行的垃圾收集器的性能往往比那些允许使用更多内存的垃圾收集器更差。
  • 在这种特殊情况下,机器上还有其他(本机)应用程序无法承受 GCed 应用程序占用这么多内存。

标签: c# .net garbage-collection


【解决方案1】:

我不知道常规 CLR 有任何此类选项。我想如果你实现自己的 CLR 主机,你可以控制它。

但是,我不同意您对堆如何增长的评估。堆增长是因为您的应用程序正在分配和持有对象。

您可以采取一些措施来限制内存使用量。请参阅此问题以获取一些输入:Reducing memory usage of .NET applications?

【讨论】:

  • 这是观察到的行为:系统循环运行,工作集大小无限增长。当 GC 在代码中显式运行时,每隔一段时间,工作集大小保持不变。我意识到这里发生了一些可疑的事情,但是运行 GC 使 WS 保持不变这一事实告诉我,应用程序没有持有对象。
  • 请记住,CLR 代表您的应用程序管理操作系统分配的内存。因此,您不一定期望在清理后看到工作集大小立即下降。 GC 会自行调整以获得更好的性能,如果不需要内存段,它们最终会被释放给操作系统。
【解决方案2】:

我还没有尝试过,但是您可以尝试调用 SetProcessWorkingSetSizeEx 并传入正确的标志来强制您的进程永远不会获得超过这么多的内存。我不知道 GC 是否会考虑到这一点并更频繁地清理,或者您是否只会得到 OutOfMemoryExceptions。

【讨论】:

    【解决方案3】:

    内存管理器让主机 提供一个接口,通过该接口 CLR 将请求所有内存 分配。它取代了两者 Windows® 内存 API 和标准 C CLR 分配例程。而且, 该接口允许 CLR 通知 主机的后果 失败的特定分配(对于 例如,内存分配失败 从持有锁的线程可能有 某些可靠性后果)。它 还允许主机自定义 CLR 对分配失败的响应, 范围从 OutOfMemoryException 一直被抛出 过程被拆除。主人 也可以使用此管理器重新捕获 通过卸载从 CLR 中获取内存 未使用的应用程序域和强制垃圾 收藏。内存管理器 接口列在

    来源和更多:http://msdn.microsoft.com/en-us/magazine/cc163567.aspx#S2

    编辑:

    我其实不建议你自己管理内存,因为你进入的越多,你可能会遇到更多的问题,相反,CLR 完美地完成了这项任务。

    但如果你说我一个人处理事情很重要,那我什么都做不了。

    【讨论】:

    • 这听起来不像我想做的事情。我希望有一个可配置的开关,就像在 Java 中一样。事实上,我正在挠头,试图弄清楚为什么没有这样的开关。我的意思是,在某处,某些东西正在根据某些限制/启发式决定何时运行 GC,并且希望能够配置该限制似乎是合理的。再次.. Java 允许这样做..
    猜你喜欢
    • 2011-02-04
    • 2010-12-25
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    相关资源
    最近更新 更多