我们使用机器学习技术将英文博客翻译为简体中文。您可以点击导航栏中的“中文(简体)”切换到英文版本。
为 Amazon ECS 和 亚马逊云科技 Lambda 配置.NET 垃圾回收
.NET 开发人员依靠.NET 的自动内存分配和垃圾回收 (GC) 机制来处理其应用程序的内存需求。对于大多数用例,开发人员不必担心 GC。但是,在.NET 应用在内存受限的环境(例如容器和
Amazon Elastic Container Service (ECS)
.NET 容器应用程序作为
任务的 cgroup 层次结构和任务中的各个容器是在启动 ECS 任务时创建的。任务的内存设置是为父级 cgroup 配置的,这限制了用于容器的子 cgroup 的内存量。但是,.NET GC 不支持遍历 cgroup 层次结构来确定可用内存量。这意味着,如果仅在任务定义级别配置内存,则.NET GC 不会看到 cgroup 的内存限制,而是检测底层主机计算的内存大小。
举例来说,运行以下应用程序将报告.NET GC 认为可用的可用内存。如果您使用 Fargate 将其部署为 ECS 任务,且最小内存设置为 0.5GB,则应用程序将报告有 4GB 的可用内存。4GB 来自底层主机计算。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Memory Test");
app.MapGet("/memory", () =>
{
return GC.GetGCMemoryInfo().TotalAvailableMemoryBytes.ToString("N0");
});
app.Run();
这会导致当.NET GC 检测到.NET 进程接近为 ECS 任务配置的 0.5GB 限制时,它不会积极释放堆中未使用的内存。这可能会触发 OutofMemoryException 并关闭容器。
如果在 ECS 任务定义中对容器定义设置了硬内存限制,则容器的 cgroup 将设置内存限制,.NET GC 将看到正确的可用内存量供其管理。您可以在控制台的 “环境” 部分为任务定义设置硬盘内存限制。此容器硬盘内存限制也可以通过 亚马逊云科技 软件开发工具包、
将新的任务定义部署到 ECS 后,上面的示例代码现在将正确地报告 GC 有 0.5GB 的可用内存。
如果任务定义定义了多个容器,则需要根据需要在不同的容器中分配任务定义的内存。
亚马逊云科技 .NET 部署工具
在最新版本的
亚马逊云科技 Lambda
Lambda 中的.NET 代码也可以在内存受限的环境中运行。Lambda 函数的最小内存大小为 128 MB。与 Fargate 一样,Lambda 使用 Linux 的 cgroup 根据 Lambda 函数配置的内存大小限制 CPU 和内存设置。但是,对于 Lambda,cgroup 的使用在.NET 运行时中是完全隐藏的。这再次导致.NET GC 认为可用的内存比实际情况还要多。
例如,如果您使用内存大小为 128MB 部署以下函数,则它报告的内存大小可能会大于 128MB。
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace LambdaMemoryCheck;
public class Function
{
public string FunctionHandler()
{
return GC.GetGCMemoryInfo().TotalAvailableMemoryBytes.ToString("N0");
}
}
与 ECS 不同,Lambda 没有可以设置的容器硬内存限制。要告知.NET GC 有多少内存可用,你可以设置.NET GC 知道要查找的 dotnet_gcheapHardLim it 环境变量。 dotnet_gcheapHardLimit 的值 是 GC 本身也应该限制 的十六进制字节数。为方便起见,下表给出了可用 Lambda 配置的十六进制值,最大为 1GB。
Lambda | hexadecimal |
---|---|
128MB | 0x8000000 |
192MB | 0xC000000 |
256MB | 0x10000000 |
320MB | 0x14000000 |
384MB | 0x18000000 |
448MB | 0x1C000000 |
512MB | 0x20000000 |
576MB | 0x24000000 |
640MB | 0x28000000 |
704MB | 0x2C000000 |
768MB | 0x30000000 |
832MB | 0x34000000 |
896MB | 0x38000000 |
960MB | 0x3C000000 |
1024MB | 0x40000000 |
dotnet_gcheapHardLim it 环境变量可以使用任何 亚马逊云科技 开发工具包和工具以编程方式进行设置。也可以在 亚马逊云科技 控制台中进行设置,也可以使用适用于 Visual Studio 的
结论
如果您的.NET 应用程序遇到内存问题,我们建议您使用容器硬内存限制来调整 GC,或者使用 dotn et_gcheapHardLimit 环境变量用于 Lambd a 函数。有关.NET GC 配置设置的更多信息,请查看
将来,亚马逊云科技和微软希望让.NET GC自动理解这些环境中的内存限制。微软已经打开了一个
特别感谢微软.NET 团队的
*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。