当 App Service Plan 有 7 GiB 时,WebJob 只能访问 2 GiB 内存
WebJob only has access to 2 GiB of memory when App Service Plan has 7 GiB
我有一个如下所示的 Azure 应用服务计划,它应该有 7 GB 的内存。
P2V2
420 total ACU
7 GB memory
Dv2-Series compute equivalent
83.22 USD/Month (Estimated)
我正在使用它来托管具有单个连续 WebJob 的单个应用程序。当然有应用程序本身的网站,但我根本不使用它。
此外,我的服务计划中只有 1 个应用程序实例,所以这不是因为多个实例共享总可用 7 GiB 内存。
服务计划有 2 个部署槽,1 个用于生产,1 个用于暂存。两个应用程序(在生产和暂存中)都已关闭,因为 WebJob 可以在应用程序本身关闭时保持 运行ning。
这是我看到的令人费解的地方。在 App Service Plan 概述页面上,它说我使用了大约 45% 的可用总内存。
但我 运行 有时会遇到 OutOfMemoryException,所以我开始检查我的 WebJob 实际使用了多少内存。
事实证明它使用了 2 GiB 可用物理内存中的 1.6 GiB,而不是我期望的 7 GiB。
我获取当前内存的方式是通过以下代码
var currentMemory = Process.GetCurrentProcess().PrivateMemorySize64;
var totalMemory = GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
This property value will be the value of the COMPlus_GCHeapHardLimit environment variable, or the Server.GC.HeapHardLimit value in runtimeconfig.json, if either is set.
If the program is run in a container, this value is an implementation-defined fraction of the container's size.
Otherwise, the value of the property is the physical memory on the machine that was available for the garbage collector to use when the last garbage collection occurred.
因为我没有环境变量,runtimeconfig.json 设置并且它不是容器,我认为 GC.GetGCMemoryInfo().TotalAvailableMemoryBytes
正确返回虚拟机上我的 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 运行s 作为一个独立于网站的进程。虽然症状是一样的。看来我的 WebJob 是 JIT 到 32 位而不是 64 位。
我的 WebJob 构建配置
.NET 6 Console Application
Platform: Any CPU
无论如何,我的应用服务配置设置为 x64,如下所示。
我试图了解我做错了什么,因为我认为 Azure 在这里做的是正确的。
我正在使用 Azure App Service 来 运行 WebJob,所以我的目标是使用可用的 smallest/cheapest SKU 最大化 WebJob 的可用内存。
我发现问题在于我如何通过在我的 ADO 管道中创建的 run.cmd
启动脚本 运行 我的 WebJob。
dotnet MyWebJob.dll
导致 GC.GetGCMemoryInfo().TotalAvailableMemoryBytes
return 2 GiB 作为我的 WeJob 的总可用内存,而我的 WebJob 本身 Process.GetCurrentProcess().PrivateMemorySize64
仅消耗 1.5 GiB 的内存。
由于我的 ADO 管道还生成一个特定于平台的可执行文件,Windows,我还有一个可以 运行 的 EXE。通过调用 EXE MyWebJob.exe
启动我的 WebJob 结果 GC.GetGCMemoryInfo().TotalAvailableMemoryBytes
return 5.5 GiB 作为我的 WeJob 的总可用内存,而我的 WebJob 本身 Process.GetCurrentProcess().PrivateMemorySize64
膨胀到 3.5 GiB 内存。
这两种不同行为的原因是 Path
环境变量同时包含 dotnet SDK x86 和 x64,在值中 dotnet x86 在 dotnet x64 之前。结果,当我执行 dotnet MyWebJob.dll
时,系统正在使用 x86 dotnet 运行time,这在调试控制台中很明显。
C:\home>dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.100
Commit: 9e8b04bbff
Runtime Environment:
OS Name: Windows
OS Version: 10.0.14393
OS Platform: Windows
RID: win10-x86
Base Path: C:\Program Files (x86)\dotnet\sdk.0.100\
Host (useful for support):
Version: 6.0.0
Commit: 4822e3c3aa
我修改了负责为我的 WebJob 生成启动脚本的 ADO 任务,以明确使用 x64 版本的 dotnet。 [01/07/2022 00:21:06 > 52cb62: INFO] C:\local\Temp\jobs\continuous\MyWebJob\n04q3opt.krt>"C:\Program Files\dotnet\dotnet.exe" MyWebJob.dll
这解决了问题。
结果与 运行 直接执行 EXE 相同,而不使用 dotnet
,如上所示。
我有一个如下所示的 Azure 应用服务计划,它应该有 7 GB 的内存。
P2V2
420 total ACU
7 GB memory
Dv2-Series compute equivalent
83.22 USD/Month (Estimated)
我正在使用它来托管具有单个连续 WebJob 的单个应用程序。当然有应用程序本身的网站,但我根本不使用它。
此外,我的服务计划中只有 1 个应用程序实例,所以这不是因为多个实例共享总可用 7 GiB 内存。
服务计划有 2 个部署槽,1 个用于生产,1 个用于暂存。两个应用程序(在生产和暂存中)都已关闭,因为 WebJob 可以在应用程序本身关闭时保持 运行ning。
这是我看到的令人费解的地方。在 App Service Plan 概述页面上,它说我使用了大约 45% 的可用总内存。
但我 运行 有时会遇到 OutOfMemoryException,所以我开始检查我的 WebJob 实际使用了多少内存。
事实证明它使用了 2 GiB 可用物理内存中的 1.6 GiB,而不是我期望的 7 GiB。
我获取当前内存的方式是通过以下代码
var currentMemory = Process.GetCurrentProcess().PrivateMemorySize64;
var totalMemory = GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
This property value will be the value of the COMPlus_GCHeapHardLimit environment variable, or the Server.GC.HeapHardLimit value in runtimeconfig.json, if either is set.
If the program is run in a container, this value is an implementation-defined fraction of the container's size.
Otherwise, the value of the property is the physical memory on the machine that was available for the garbage collector to use when the last garbage collection occurred.
因为我没有环境变量,runtimeconfig.json 设置并且它不是容器,我认为 GC.GetGCMemoryInfo().TotalAvailableMemoryBytes
正确返回虚拟机上我的 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 运行s 作为一个独立于网站的进程。虽然症状是一样的。看来我的 WebJob 是 JIT 到 32 位而不是 64 位。
我的 WebJob 构建配置
.NET 6 Console Application
Platform: Any CPU
无论如何,我的应用服务配置设置为 x64,如下所示。
我试图了解我做错了什么,因为我认为 Azure 在这里做的是正确的。
我正在使用 Azure App Service 来 运行 WebJob,所以我的目标是使用可用的 smallest/cheapest SKU 最大化 WebJob 的可用内存。
我发现问题在于我如何通过在我的 ADO 管道中创建的 run.cmd
启动脚本 运行 我的 WebJob。
dotnet MyWebJob.dll
导致 GC.GetGCMemoryInfo().TotalAvailableMemoryBytes
return 2 GiB 作为我的 WeJob 的总可用内存,而我的 WebJob 本身 Process.GetCurrentProcess().PrivateMemorySize64
仅消耗 1.5 GiB 的内存。
由于我的 ADO 管道还生成一个特定于平台的可执行文件,Windows,我还有一个可以 运行 的 EXE。通过调用 EXE MyWebJob.exe
启动我的 WebJob 结果 GC.GetGCMemoryInfo().TotalAvailableMemoryBytes
return 5.5 GiB 作为我的 WeJob 的总可用内存,而我的 WebJob 本身 Process.GetCurrentProcess().PrivateMemorySize64
膨胀到 3.5 GiB 内存。
这两种不同行为的原因是 Path
环境变量同时包含 dotnet SDK x86 和 x64,在值中 dotnet x86 在 dotnet x64 之前。结果,当我执行 dotnet MyWebJob.dll
时,系统正在使用 x86 dotnet 运行time,这在调试控制台中很明显。
C:\home>dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.100
Commit: 9e8b04bbff
Runtime Environment:
OS Name: Windows
OS Version: 10.0.14393
OS Platform: Windows
RID: win10-x86
Base Path: C:\Program Files (x86)\dotnet\sdk.0.100\
Host (useful for support):
Version: 6.0.0
Commit: 4822e3c3aa
我修改了负责为我的 WebJob 生成启动脚本的 ADO 任务,以明确使用 x64 版本的 dotnet。 [01/07/2022 00:21:06 > 52cb62: INFO] C:\local\Temp\jobs\continuous\MyWebJob\n04q3opt.krt>"C:\Program Files\dotnet\dotnet.exe" MyWebJob.dll
这解决了问题。
结果与 运行 直接执行 EXE 相同,而不使用 dotnet
,如上所示。