首页 > 系统相关 >OOM看 之 低端内存保护机制lowmem_reserve

OOM看 之 低端内存保护机制lowmem_reserve

时间:2023-06-17 18:14:19浏览次数:46  
标签:ratio zone OOM 内存保护 lowmem 内存 pages reserve

一 什么是lowmem_reserve

为了防止高端内存申请者”偷用”太多的低端内存,内核的内存页分配器提供了一种叫做”lowmem_reserve”的机制防止来防止高端内存的申请者占用太多低端内存,这个机制是通过”lowmem_reserve_ratio”这个调节接口来决定低端内存被高端内存占用的程度。

lowmem_reserve_ratio在内核中是一个整形数组,可通过如下proc接口文件访问(linux-5.10版本):

cat /proc/sys/vm/lowmem_reserve_ratio
256    256    32    0    0

这个数组的默认值在内核定义如下:

int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES] = {
#ifdef CONFIG_ZONE_DMA
        [ZONE_DMA] = 256,
#endif
#ifdef CONFIG_ZONE_DMA32
        [ZONE_DMA32] = 256,
#endif
        [ZONE_NORMAL] = 32,
#ifdef CONFIG_HIGHMEM
        [ZONE_HIGHMEM] = 0,
#endif
        [ZONE_MOVABLE] = 0,
};

需要注意的是,lowmem_reserve_ratio只是一个系数,并不是直接可用的数值,内核函数setup_per_zone_lowmem_reserve()通过lowmem_reserve_ratio这个系数来计算出各个zone的保留内存。各个zone的保留内存值在/proc/zoneinfo获取到,如下所示:

Node 0, zone      DMA
……
  pages free     2655
        min      70
        low      87
        high     104
        spanned  4095
        present  3998
        managed  3840
        cma      0
        protection: (0, 2740, 3567, 3567, 3567)

这里的protections可作为一个判断这个zone是否有足够分配内存的一个因素。

在上例中,如果一个normal内存页(index=2)要申请DMA的内存且使用到watermark[WMARK_HIGH]水线,内核会做如下判断:

free_pages = 2655 
watermark(WMARK_HIGH)+protection[2] = 104+3567 = 3671

因此free_pages < watermark(WMARK_HIGH)+protection[2] ,so,这次分配会失败。这里使用protection[2]是因为normal内存的index是2;如果请求的是DMA内存,则index=0,则使用protection[0]。

二 如何计算各个zone的lowmem_reserve

其实就是关于如何计算各个zone的protection[]。

系统在初始化时会调用根据setup_per_zone_lowmem_reserve计算各个zone的lowmem_reserve;此外,还可以在系统启动后通过/proc/sys/vm/lowmem_reserve_ratio接口调整各个zone的lowmem_reserve,具体计算公式参考如下伪代码:

  (i < j):
    zone[i]->protection[j]
    = (total sums of managed_pages from zone[i+1] to zone[j] on the node)
      / lowmem_reserve_ratio[i];
  (i = j):
     (should not be protected. = 0;
  (i > j):
     (not necessary, but looks 0)

有了伪代码,我们就更好理解下面的内核的计算代码,如下所示:

/*
 * setup_per_zone_lowmem_reserve - called whenever
 *      sysctl_lowmem_reserve_ratio changes.  Ensures that each zone
 *      has a correct pages reserved value, so an adequate number of
 *      pages are left in the zone after a successful __alloc_pages().
 */
static void setup_per_zone_lowmem_reserve(void)
{
        struct pglist_data *pgdat;
        enum zone_type i, j;

        for_each_online_pgdat(pgdat) {
                for (i = 0; i < MAX_NR_ZONES - 1; i++) {
                        struct zone *zone = &pgdat->node_zones[i];
                        int ratio = sysctl_lowmem_reserve_ratio[i];
                        bool clear = !ratio || !zone_managed_pages(zone);
                        unsigned long managed_pages = 0;
            /**
                i=0: zone[DMA].lowmem_reserve[DMA32] = managed_pages(zone[DMA32]) / ratio[DMA]
                          zone[DMA].lowmem_reserve[NORMAL] = (managed_pages(zone[NORMAL]) + managed_pages(zone[DMA32])) / ratio[DMA]
                i=1:   zone[DMA32].lowmem_reserve[NORMAL] = managed_pages(zone[NORMAL]) / ratio[DMA32]
            **/
                        for (j = i + 1; j < MAX_NR_ZONES; j++) {
                                struct zone *upper_zone = &pgdat->node_zones[j];

                                managed_pages += zone_managed_pages(upper_zone);

                                if (clear)
                                        zone->lowmem_reserve[j] = 0;
                                else
                                        zone->lowmem_reserve[j] = managed_pages / ratio;
                        }
                }
        }

        /* update totalreserve_pages */
        calculate_totalreserve_pages();
}

 

三 lowmem_reserve对于内存页分配的影响

内核在分配内存页时会调用__zone_watermark_ok()函数去检查zone中是否有足够的内存,其中的一个判定条件就是:

if (free_pages <= min + z->lowmem_reserve[highest_zoneidx])

其中,free_pages就是对应zone中的剩余可用内存;而min就是经过计算后的水线;z->lowmem_reserve[highest_zoneidx]就是该zone对于highest_zoneidx的预留内存。如果上述条件不满足,本次扫描会跳过这个zone,表示这个zone内存不足。

从这个代码逻辑来看,lowmem_reserve对于内存页的分配确实起着至关重要的作用,决定着内存分配成败。

在实际实践过程中如果发生OOM时看到free内存并未触及到水线时,可以看看是否是由于z->lowmem_reserve影响~ 

标签:ratio,zone,OOM,内存保护,lowmem,内存,pages,reserve
From: https://www.cnblogs.com/liuhailong0112/p/17475983.html

相关文章

  • K8S的OOM和cpu节流
    介绍使用Kubernetes时,内存不足(OOM)错误和CPU节流是云应用程序中资源处理的主要难题。这是为什么?云应用程序中的CPU和内存要求变得越来越重要,因为它们与您的云成本直接相关。通过limits和requests,您可以配置pod应如何分配内存和CPU资源,以防止资源匮乏并调整云成本......
  • Adobe Lightroom Classic 2022 V11【图片后期处理软件】直装版安装教程
    Lightroom2022是一款功能强大、非常专业的图片编辑软件,由著名公司Adobe制作,可以为用户编辑照片。这个软件和我们熟悉的ps有很大的不同。它主要帮助用户简单方便地管理电脑上的照片,甚至完成照片的一些修改,比如去除不需要的物体,校正照片,增强照片的颜色。在生活中,很多人经常处理照片,但......
  • TikTok 英国业务亏损、苹果从中国应用商店下架近4万款游戏、Zoom 接受调查等|Decode th
    DecodetheWeek≠音视频技术周刊 图片来源于电影《心灵奇旅》NewsBriefing1. Adobe终止了对Flash插件的支持。上周,在经历了漫长而缓慢的衰退之后,Flash终于迎来了它的最后一站。2.亚马逊收购Wondery,对标Spotify亚马逊最近在播客市场进行了大规模的收购。它目前正在收购播客......
  • 飞步fireboom 不同库关联查询
    fireboom关联查询demo列表queryMyQuery($skip:Int=10,$take:Int=10,$tid:Int){list:iot_device_bill_findManydevice_information(skip:$skip,take:$take){tenant_id@export(as:"tid")tenant_info:_join{data:iot_core_findFirstsys_......
  • bloom filter
      在javaEyes上找到一篇挺有用的文章,希望能对大家理解Bloomfilter有帮助  1Overview   Bloomfilter最早由 BurtonHowardBloom提出,是一种用于判断成员是否存在于某个集合中的数据结构。 Bloomfilter的判断基于概率论:  如果某个成员存在于集合中,那么Bloomfilte......
  • bloomFilter_demo
    参考博客:(14条消息)布隆(BloomFilter)过滤器入门_布隆过滤器入门_qq_39093474的博客-CSDN博客5分钟搞懂布隆过滤器,亿级数据过滤算法你值得拥有!-知乎(zhihu.com)BloomFilterTest.javapackagecom.hmb;importcom.google.common.hash.BloomFilter;importcom.google.co......
  • KOOM原理分析之一些基础知识
    文章目录资料Profile工具的使用内存性能分析器概览内存计算方式查看内存分配情况(Record一段)查看全局JNI引用原生内存性能分析器将堆转储另存为HPROF文件HPROFAgentBinaryDumpFormat(format=b)HandlingofArrays资料使用内存性能分析器查看应用的内存使用情况HPROFAgentPr......
  • ES无法启动_OOM_Exception in thread "main" java.lang.RuntimeException: starting j
    1.报错显示[root@iZ7xv2ya5ap2bnetr231koZ~]#dockerlogsesExceptioninthread"main"java.lang.RuntimeException:startingjavafailedwith[1]output:##ThereisinsufficientmemoryfortheJavaRuntimeEnvironmenttocontinue.#Nativememorya......
  • Lightroom Classic 2022(lrc2022)中文版 win/mac
    LightroomClassic2022是Adobe公司推出的一款图像处理软件,主要用于数字照片的编辑、整理和输出。它提供了丰富的编辑工具和管理功能,可以帮助用户高效地管理和处理数千张照片。在2022年版本中,增加了新的功能,如批量编辑、智能搜索、更快的性能和改进的界面等。主要特点包括:统一的......
  • 按选择的实体objectid来zoom时,发现一个很特别的实体dbtext
    dbtext取得其GeometricExtents时,发现ext特别大,暂时不知道什么原因,所以在程序中把文字去掉了。这一个东西测试了很长时间。publicstaticvoidZoomObjects(thisEditored,ObjectIdCollectionidCol){Documentdoc=AcadApp.DocumentManager.MdiActiveDocument;......