我有一个如下的 Azure 应用服务计划,它应该有 7 GB 的内存。
P2V2
420 total ACU
7 GB memory
Dv2-Series compute equivalent
83.22 USD/Month (Estimated)
我正在使用它来托管具有单个 Continuous WebJob 的单个应用程序。当然有应用程序本身的网站,但我根本不使用它。
此外,我的服务计划中只有 1 个应用程序实例,因此不是因为多个实例共享总可用 7 GiB 内存。
服务计划有 2 个部署槽,1 个用于生产,1 个用于暂存。两个应用程序(生产中和暂存)都已关闭,因为 WebJob 可以在应用程序本身关闭时继续运行。
这是我看到的令人费解的地方。从应用服务计划概述页面中,它说我使用了大约 45% 的可用总内存。
但是我有时会遇到 OutOfMemoryException,所以我开始检查我的 WebJob 实际使用了多少内存。
事实证明,它使用了 2 GiB 可用物理内存中的 1.6 GiB,而不是我期望的 7 GiB。
我获取当前内存的方式是通过以下代码
var currentMemory = Process.GetCurrentProcess().PrivateMemorySize64;
var totalMemory = GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
此属性值将是 COMPlus_GCHeapHardLimit 环境变量的值,或 runtimeconfig.json 中的 Server.GC.HeapHardLimit 值(如果已设置)。
如果程序在容器中运行,则此值是容器大小的实现定义的一部分。
否则,该属性的值是上次垃圾收集发生时可供垃圾收集器使用的机器上的物理内存。
由于我没有设置环境变量 runtimeconfig.json 并且它不是容器,因此我认为GC.GetGCMemoryInfo().TotalAvailableMemoryBytes
正确地返回了 VM 上我的 WebJob 可用的总物理内存,即 2 GiB。
感谢 Vova 在下面的评论,我还找到了这篇文章。https://docs.microsoft.com/en-us/azure/app-service/faq-availability-performance-application-issues#i-see-the-message--worker-process-requested-recycle-due-to --percent-memory--limit---how-do-i-address-this-issue-
这确实有道理;同时,在我看来,这篇文章是针对应用服务本身的。WebJob 作为独立于网站的进程运行。虽然症状是一样的。看来我的 WebJob 是 JIT 到 32 位而不是 64 位。
我的 WebJob 构建配置
.NET 6 Console Application
Platform: Any CPU
我试图了解我做错了什么,因为我认为 Azure 在这里做的是正确的事情。
我正在使用 Azure 应用服务来运行 WebJob,因此我的目标是使用最小/最便宜的 SKU 来最大化 WebJob 的可用内存。