ASP.NET Core 8 的内存占用可以更低吗?
Maoni Stephens 是 .NET 垃圾回收器 (GC) 的首席架构师之一,她在2023年8月份发表了一篇关于 .NET GC 新功能的博客文章,该功能称为 Dynamic Adaption To Application Sizes (DATAS),该功能将随 .NET 8 一起提供。此功能将在应用运行时自动增加或减少服务器 GC 模式下的托管堆数量。它减少了 .NET 应用使用的内存总量,使服务器 GC 模式成为内存受限环境(如 Docker 容器或 Kubernetes Pod)的可行选项,这些环境可以访问多个逻辑 CPU 内核。
服务器 GC 模式和工作站 GC 模式之间的差异
工作站模式最初是为客户端应用程序设计的。过去,执行应用代码的线程会停止,直到 GC 运行完成。在桌面应用程序中,您不希望在几毫秒甚至几秒钟内出现冻结,因此 Workstation GC 经过调整,可以更频繁地执行运行,并更快地完成单个运行。从 .NET Framework 4.0 开始,我们还具有后台 GC 运行模式,可最大程度地减少线程被阻塞的时间。
相比之下,服务器 GC 旨在最大限度地提高服务的吞吐量,这些服务将随着时间的推移接收短期请求。GC 运行频率较低,但可能需要更长的时间。最后,您将在 GC 上运行上花费更少的时间,而将更多的时间花在服务代码上。
最明显的区别如下:Workstation GC 仅使用单个托管堆。托管堆由以下子堆组成:
- 小对象堆 (SOH) 及其三代 0、1 和 2。小于 85,000 字节的对象将在此处分配。
- 大型对象堆 (LOH),用于大于或等于 85,000 字节的对象。
- 固定对象堆 (POH),主要由为此执行互操作和固定缓冲区的库使用(例如,用于网络或其他 I/O 方案)。
在服务器 GC 模式下,您将拥有多个这样的托管堆,默认情况下每个逻辑 CPU 内核一个,但这可以通过 GCHeapCount 进行调整。
托管堆数量增加,以及 GC 运行执行频率较低,是解释为什么服务器 GC 模式下内存消耗要高得多的重要因素。
但是,如果您希望从服务器 GC 模式中受益,同时在运行时动态调整托管堆的数量,该怎么办?一个典型的方案是在云中运行的服务,它必须在特定的突发时间处理大量请求,但之后它应该缩减以减少内存消耗。到目前为止,除了使用不同的配置值重新启动服务外,您没有办法实现这一点。纵向扩展也需要重新启动,因此许多开发团队只是试图通过 GCHeapCount 和 ConserveMemory 选项找到折衷方案。
这时,.NET 8 带来了一项名为“动态适应应用程序大小”(DATAS) 的新功能就派上用场了。DATAS 在运行时将按以下方式运行:
- GC 将仅从单个托管堆开始。
- 根据称为“吞吐量成本百分比”的指标,GC 将决定增加托管堆的数量是否可行。这将在每三次 GC 运行时进行评估。
- 还有一个称为“空间成本”的指标,GC 使用它来决定是否应该减少托管堆的数量。
- 如果 GC 决定增加或减少托管堆的数量,它将阻塞您的线程(类似于压缩 GC 运行)并创建或删除托管堆。相应的内存区域将被移动。当涉及到托管堆中内存的内部组织时,在 .NET 6 和 .NET 7 中从段切换到区域,使此方案成为可能。
优点和缺点?
DATAS 允许在内存受限环境中使用服务器 GC 模式,例如在 Docker 容器、Kubernetes Pod 。在您的服务将受到大量请求的攻击突发期间,GC 将动态增加托管堆的数量,以便从服务器 GC 的优化吞吐量设置中受益。突发结束后,GC 将再次减少托管堆的数量,从而减少应用使用的内存总量。即使在突发期间,GC 也可能选择将托管堆增加到每个逻辑 CPU 内核少于 1 个,因此您最终可能会使用更少的内存,而无需手动配置托管堆的数量。
请记住:当应用只有一个逻辑 CPU 内核可用时,应始终使用 Workstation GC 模式。仅当应用有两个或更多可用内核时,服务器 GC 模式才有用。此外,我建议您验证您是否确实需要服务器 GC 模式。使用 K6 或 NBomber 等工具来衡量 Web 应用的吞吐量。如果仔细设计了应用的内存使用情况,则吞吐量可能根本没有差异。永远记住:.NET GC 只会在分配内存时执行其运行。
DATAS 是一项很棒的新功能,它将 Workstation GC 和 Server GC 的优势结合在一起:您开始时内存更少,当请求激增时,GC 可以动态扩展其托管堆的数量以提高吞吐量。当请求数在以后的某个时间点减少时,也可以减少托管堆的数量以释放内存。
DATAS 可以在.NET 8 产品中使用,但是并没有默认启用,需要手动进行指定:若要试用 DATAS,需要安装 .NET 8 SDK,创建一个 .NET 8 应用(例如 ASP.NET Core),然后可以将以下两行添加到 .csproj 文件:
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
<GarbageCollectionAdapatationMode>1</GarbageCollectionAdapatationMode>
</PropertyGroup>
您还可以在构建项目时通过命令行参数指定它:
dotnet build /p:ServerGarbageCollection=true /p:GarbageCollectionAdapatationMode=1
或者在 runtimeconfig.json 中:
"configProperties": {
"System.GC.Server": true,
"System.GC.DynamicAdaptationMode": 1
}
或者通过环境变量:
set DOTNET_gcServer=1
set DOTNET_GCDynamicAdaptationMode=1
请记住:使用上述方法之一时,不得设置 GCHeapCount 选项。如果这样做,GC 将只使用指定数量的堆,而不会激活 DATAS。同样重要的是:如果要在工作站模式下运行,只需将 ServerGarbageCollection 或相应的配置属性/环境变量分别设置为 false 或零。
默认情况下,我的 ASP.NET Core 应用将使用哪种 GC 模式?
你的 ASP.NET Core 应用可以访问多少个逻辑 CPU 内核?如果小于两个,则将使用 Workstation GC 模式。否则,默认情况下将激活服务器 GC 模式。因此,在 Docker、Kubernetes 或云环境中为应用指定约束时要特别小心,因为这些环境可能会突然进入另一个 GC 模式,占用的内存比预期的要多。
ASP.NET Core 8 的内存占用可以更低吗?的更多相关文章
- ASP.NET Core - 缓存之内存缓存(上)
1. 缓存 缓存指的是在软件应用运行过程中,将一些数据生成副本直接进行存取,而不是从原始源(数据库,业务逻辑计算等)读取数据,减少生成内容所需的工作,从而显著提高应用的性能和可伸缩性,使用好缓存技术, ...
- ASP.NET Core - 缓存之内存缓存(下)
话接上篇 [ASP.NET Core - 缓存之内存缓存(上)],所以这里的目录从 2.4 开始. 2.4 MemoryCacheEntryOptions MemoryCacheEntryOption ...
- asp.net core webapi Session 内存缓存
Startup.cs文件中的ConfigureServices方法配置: #region Session内存缓存 services.Configure<CookiePolicyOptions&g ...
- 在ASP.NET Core 2.0中使用MemoryCache
说到内存缓存大家可能立马想到了HttpRuntime.Cache,它位于System.Web命名空间下,但是在ASP.NET Core中System.Web已经不复存在.今儿个就简单的聊聊如何在ASP ...
- 为什么我的会话状态在ASP.NET Core中不工作了?
原文:Why isn't my session state working in ASP.NET Core? Session state, GDPR, and non-essential cookie ...
- asp.net core 缓存和Session
缓存 缓存在内存中 ASP.NET Core 使用 IMemoryCache内存中缓存是使用依赖关系注入从应用中引用的服务. 请在ConfigureServices中调用AddMemoryCache( ...
- ASP.Net Core使用分布式缓存Redis从入门到实战演练
一.课程介绍 人生苦短,我用.NET Core!缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力. 所以经常要用到且不会频繁改变且被用户共享的 ...
- ASP.NET Core - 缓存之分布式缓存
分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护. 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时. 与其 ...
- ASP.NET Core 1.0 静态文件、路由、自定义中间件、身份验证简介
概述 ASP.NET Core 1.0是ASP.NET的一个重要的重新设计. 例如,在ASP.NET Core中,使用Middleware编写请求管道. ASP.NET Core中间件对HttpCon ...
- ASP.NET Core 源码学习之 Logging[1]:Introduction
在ASP.NET 4.X中,我们通常使用 log4net, NLog 等来记录日志,但是当我们引用的一些第三方类库使用不同的日志框架时,就比较混乱了.而在 ASP.Net Core 中内置了日志系统, ...
随机推荐
- 文心一言 VS 讯飞星火 VS chatgpt (92)-- 算法导论8.3 5题
五.用go语言,在本节给出的第一个卡片排序算法中,为排序 d 位十进制数,在最坏情况下需要多少轮排序?在最坏情况下,操作员需要记录多少堆卡片? 文心一言: 你提到的第一个卡片排序算法可能是指的基数排序 ...
- MySQL实战实战系列 01 基础架构:一条SQL查询语句是如何执行的?
这是专栏的第一篇文章,我想来跟你聊聊 MySQL 的基础架构.我们经常说,看一个事儿千万不要直接陷入细节里,你应该先鸟瞰其全貌,这样能够帮助你从高维度理解问题.同样,对于 MySQL 的学习也是这样. ...
- mpi转以太网连接300PLC与施耐德 Quantum PLC 通讯
S7300 PLC转以太网无需编程与施耐德 Quantum PLC modbusTCP通信 方案介绍: 西门子300PLC转以太网不需要编写程序通过兴达易控MPI-ETH-XD1.0与施耐德 Quan ...
- 关于初次new springboot项目
如果是新手初学,然后做springboot项目报各种错,改来改去最终都无法出现successful字样. 请先检查,maven环境是否配好. maven环境决定你下载依赖的速度,以及能否下载成功. m ...
- 基于AvaSpe 2048测定物体的光谱曲线
本文介绍基于AvaSpec-ULS2048x64光纤光谱仪测定植被.土壤等地物高光谱曲线的方法. AvaSpec是由荷兰著名的光纤光谱仪器与系统开发公司Avantes制造的系列高性能光谱仪,广 ...
- Linux 中如何安全地抹去磁盘数据?
哈喽大家好,我是咸鱼 离过职的小伙伴都知道,离职的时候需要上交公司电脑,但是电脑里面有许多我们的个人信息(聊天记录.浏览记录等等) 所以我们就需要先把这些信息都删除,确保无法恢复之后才上交 即有些情况 ...
- 网络层IP数据包
网络层 功能 选择数据通过网络(IP地址)的最佳路径 协议字段 版本号(4bit):指IP协议版本.并且通信双方使用的版本必须一致,目前我们使用的是IPv4,表示为0100 十进制 是4 首部长度(4 ...
- Ocserv整合Radius认证
目前社区主流SSL VPN有两个分支:openvpn和ocserv,通过官网和检索到的资料对比前者服务端比较强大,后者客户端和移动端支持更好,二者并不兼容: 另外前者商业化封装更好,偏向商业化,后者对 ...
- win11中无法识别STM32 BOOTLOADER的解决方法
如图,按照PYBoard的官方手册说可以直接右键选择自动更新驱动即可.但是我在WIN11上并没有成功. 主要是原因是,DFU模式下的STM设备驱动程序没有自动安装成功. 解决方法是手动安装一下驱动: ...
- SyntaxError: Non-ASCII character 与 Cannot decode using encoding "ascii" 错误解决
转载请注明出处: python调试时遇到的两个相同的编码错误进行总结: 1.错误:Cannot decode using encoding "ascii", unexpected ...