【问题标题】:Limiting the maximum memory used by a C# program限制 C# 程序使用的最大内存
【发布时间】:2021-12-23 03:32:42
【问题描述】:

我需要限制 C# 程序使用的最大内存,也就是说,如果它的内存消耗超过一定的限制,它将立即崩溃,而不是继续向操作系统请求更多。

(代码已经正确且高效,但运行时内存消耗会因输入数据的不同而发生不可预测的变化。某些输入数据集仅使用几兆字节即可正确得出结论。其他会导致它使用数兆字节。在实践中,这意味着它会在虚拟内存系统疯狂地尝试满足请求时将整个机器磨碎,然后崩溃。我希望程序立即崩溃,而不是通过'磨碎整个机器停止'部分。)

这是在 64 位 Windows 上运行的;在大多数情况下,限制实际上应该是几十 GB,但以下测试用例尝试分配 1 GB;我试图让它崩溃而不是满足这个请求。

C:\t>type a.cs
using System;

class a
{
    static void Main(string[] args)
    {
                var a = new byte[1024*1024*1024];
                a[0] = 5;
                Console.WriteLine(a[0]);
    }
}

C:\t>csc a.cs
Microsoft (R) Visual C# Compiler version 3.5.0-beta4-20153-05 (20b9af91)
Copyright (C) Microsoft Corporation. All rights reserved.

https://docs.microsoft.com/en-us/dotnet/core/run-time-config/garbage-collector 建议实际上有一种方法可以将其设置为运行时参数,方法是在名为 runtimeconfig.json 的文件中指定它。文档的某些部分建议文件名需要以程序名称为前缀,而有些则不需要;我正在尝试两种方式。

C:\t>type runtimeconfig.json
{
   "runtimeOptions": {
      "configProperties": {
         "System.GC.HeapHardLimit": 209715200
      }
   }
}

C:\t>type a.runtimeconfig.json
{
   "runtimeOptions": {
      "configProperties": {
         "System.GC.HeapHardLimit": 209715200
      }
   }
}

文档还建议这可以通过设置环境变量来完成。

C:\t>set DOTNET_GCHeapHardLimit=C800000

但以上都没有任何效果。

C:\t>a
5

我是否遗漏了有关如何使用上述内容的内容?还是有其他方法可以限制最大内存使用量?

【问题讨论】:

    标签: c# .net memory memory-management heap-memory


    【解决方案1】:

    查看我在 VS2022 中创建的名为 Mime.exe 的早期 .NET 6 控制台项目,在构建期间它会在输出目录中创建一个 Mime.runtimeconfig.json 文件。所以肯定以可执行文件的名称为前缀。作为参考,这是具有工作堆限制的内容:

    {
      "runtimeOptions": {
        "tfm": "net6.0",
        "framework": {
          "name": "Microsoft.NETCore.App",
          "version": "6.0.0"
        },
        "configProperties": {
          "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
          "System.GC.HeapHardLimit": 1000000
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      假设您使用的是 powershell(使用 .net 6 测试):

      1. $Env:DOTNET_GCHeapHardLimit = 0x2000000
      2. 运行您的程序。
      3. 要检查它是否在您的 c# 代码中工作,请使用:Console.WriteLine($"{GC.GetGCMemoryInfo().TotalAvailableMemoryBytes}");

      您可能还需要考虑限制堆的数量 (DOTNET_GCHeapCount)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-25
        • 2023-03-27
        • 2017-08-12
        • 2015-03-27
        • 1970-01-01
        • 2016-11-23
        • 2011-02-13
        • 1970-01-01
        相关资源
        最近更新 更多