【App Service】.NET 应用在App Service上内存无法占用100%的问题原因

问题描述

如果使用Azure App Service部署.NET 应用,会发现在内容并没有达到100%的时候,也会出现OOM错误。这是一个什么情况呢?


image.png

大内存测试代码

   static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!"); int objunmbers = 20000; byte[][] largeArray = new byte[objunmbers][];

            Console.WriteLine("Start to create big memory object ... from 2GB"); //Console.WriteLine("Start to create big memory object ... from 20MB");
            long size = 2L * 1024 * 1024 * 1024; // 2GB //long size = 2L * 1024 * 1024 * 10; // 20MB
            int times = 1; while (size > 0)
            { if (CreateBigMemoryObject(largeArray,size, times))
                {
                    Console.WriteLine($"[{times}] Successfully created memory object of size: {size} bytes ({size / 1024 / 1024} MB)");

                    times = times + 1;
                } else {
                    Console.WriteLine($"Failed to create memory object of size: {size} bytes ({size / 1024 / 1024} MB). Trying smaller size...");
                    size = size - 100 * 1024 * 1024; // Decrease by 100MB //size = size - 1 * 1024 * 1024; // Decrease by 1MB
 } //Thread.Sleep(2000);
 }

            Console.WriteLine("Finished memory allocation attempts.");
            Console.WriteLine("sleep 5 mins");
            Thread.Sleep(5 * 60 * 1000);
            Console.WriteLine("End");
        } static bool CreateBigMemoryObject(byte[][] largeArray,long size,int index)
        { try {
                largeArray[index] = new byte[size]; return true;
            } catch (OutOfMemoryException ex)
            {
                Console.WriteLine($"OutOfMemoryException: {ex.Message}");
            } catch (Exception ex)
            {
                Console.WriteLine($"Exception: {ex.Message}");
            } return false;
        }

问题解答

在反复试验后,证明这是.NET 应用在 Azure App Service(Windows) 上才会遇见的问题。

根本原因是:.NET Core 在运行时会对 GC 堆的最大可用内存设定一个Hard Limit,而App Service中设定的值为 75%, 所以32Gb的内容最大可用24Gb。

image.png

( Manage resource usage for all GC flavors : https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#manage-resource-usage-for-all-gc-flavors )

当然,知道这个限制之后,就可以通过配置去修改它,比如通过配置 runtimeconfig.json 文件,设置 System.GC.HeapHardLimitPercent : 96 或者 System.GC.HeapHardLimit : 32,000,000,000

image.png

参考资料

Manage resource usage for all GC flavors : https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#manage-resource-usage-for-all-gc-flavors

当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容