問題描述

如果使用Azure App Service部署.NET 應用,會發現在內容並沒有達到100%的時候,也會出現OOM錯誤。這是一個什麼情況呢?

【App Service】.NET 應用在App Service上內存無法佔用100%的問題原因_App

大內存測試代碼

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。

【App Service】.NET 應用在App Service上內存無法佔用100%的問題原因_System_02

( 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

【App Service】.NET 應用在App Service上內存無法佔用100%的問題原因_microsoft_03

 

 

參考資料

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 

 


當在複雜的環境中面臨問題,格物之道需:濁而靜之徐清,安以動之徐生。 雲中,恰是如此!