DOTNET内存占用优化

很长时间以来我都在公司dotnet开发的软件上做各种性能优化,包括各种崩溃、线程池资源不足、死锁、以及很多性能慢的代码问题等,类似这种cpu相关问题都比较好查出来。
这个过程中经常遇到内存占用过高的问题,也是各种办法都试用了一遍,包括DOTNET GC相关的各种配置,还给docker加内存限制,但是一直都解决不了,比如以下这些:

  1. 服务器模式:https://learn.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector#workstation-vs-server
  2. 后台垃圾回收:https://learn.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector#background-gc
  3. 动态适应应用程序大小 (DATAS):https://learn.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector#dynamic-adaptation-to-application-sizes-datas
  4. 高内存百分比:https://learn.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector#high-memory-percent
  5. 节省内存:https://learn.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector#conserve-memory

以上全部解决不了问题,通过dump-counters诊断看,GC012代以及LOH等占用都不高,但是WorkingSet占用是它们总和的好几倍,并且长时间保持这个状态。意思就是程序实际并没有使用太多内存,但是整个进程看内存占用却很高,似乎GC工作了但并没有把内存释放回操作系统。通过dump分析内存发现大量的空闲内存,碎片也没有那么多。空闲的内存是程序曾经高负载时申请使用的,之后低负载就没有释放回操作系统。

搜索后发现了两个dotnet的issues:
https://github.com/dotnet/runtime/issues/90640
https://github.com/dotnet/runtime/issues/49317
看来遇到这个问题的不只我一个人,似乎从dotnet7开始就会有这个问题,dotnet8加入的DATAS配置也无法解决这个问题。

按照这个issue说的加这两个环境变量,验证发现真的可以解决问题,只是cpu占用会稍微多点,这个可以接受。

MALLOC_ARENA_MAX: 2
MALLOC_TRIM_THRESHOLD_: 85000

这个问题可能针对的是不太单纯的应用程序,会出现有时需要更多内存,而常规情况下只需要少量内存的情况。

posted @   Rick Carter  阅读(105)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示