背景

经常在看内存管理这块的代码时会看到这两个标记,有时候稍微不注意就会把他们搞混了,本篇博客就来聊聊他们的区别。

定义

首先这两个标记的定义如下,由此可见他们两个是不同的两个标记,表示的当然也是不同的意义:

#define ___GFP_HIGH     0x20u
#define ___GFP_HIGHMEM      0x02u

对于___GFP_HIGHMEM 标记来说,它是用来在内存申请时确定要从哪个目标zone中申请内存的。具体可以参考我的博文:
《如何从GFP确定最后申请的内存来自哪个zone?》

那么对于___GFP_HIGH 这个标记来说,申请内存时传入该标记的意义在于申请内存时,选择更加激进的策略来申请。

使用原理

我们看下它的原理,内存申请时需要传递alloc_flags,这个标志alloc_flags是从gfp_mask转换而来的:

2826 static inline int
2827 gfp_to_alloc_flags(gfp_t gfp_mask)
2828 {2829     int alloc_flags = ALLOC_WMARK_MIN | ALLOC_CPUSET;
2830     const bool atomic = !(gfp_mask & (__GFP_WAIT | __GFP_NO_KSWAPD));
2831
2832     /* __GFP_HIGH is assumed to be the same as ALLOC_HIGH to save a branch. */
2833     BUILD_BUG_ON(__GFP_HIGH != (__force gfp_t) ALLOC_HIGH);
2834
2835     /*
2836      * The caller may dip into page reserves a bit more if the caller
2837      * cannot run direct reclaim, or if the caller has realtime scheduling
2838      * policy or is asking for __GFP_HIGH memory.  GFP_ATOMIC requests will
2839      * set both ALLOC_HARDER (atomic == true) and ALLOC_HIGH (__GFP_HIGH).
2840      */
2841     alloc_flags |= (__force int) (gfp_mask & __GFP_HIGH);
2842
...

可以看到alloc_flags |= (__force int) (gfp_mask & __GFP_HIGH); 这一条就是设置ALLOC_HIGH申请标志的,因为ALLOC_HIGH和__GFP_HIGH的定义值是相等的:

#define ALLOC_HIGH      0x20 /* __GFP_HIGH set */

设置了这个alloc_flags,在哪里生效呢?也就是在申请内存时选择了特定的zone,在判断该zone的剩余空闲内存是否允许被申请时做判断使用的:

*/
2079 static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
2080               int classzone_idx, int alloc_flags, long free_pages)
2081 {2082     /* free_pages my go negative - that's OK */
2083     long min = mark;
2084     long lowmem_reserve = z->lowmem_reserve[classzone_idx];
2085     int o;
2086     long free_cma = 0;
2087
2088     free_pages -= (1 << order) - 1;
2089     if (alloc_flags & ALLOC_HIGH)
2090         min -= min / 2;
2091     if (alloc_flags & ALLOC_HARDER)
2092         min -= min / 4;
2093  #ifdef CONFIG_CMA
2094     /* If allocation can't use CMA areas don't use free CMA pages */
2095     if (!(alloc_flags & ALLOC_CMA))
2096         free_cma = zone_page_state(z, NR_FREE_CMA_PAGES);
2097 #endif
2098
2099     if (free_pages - free_cma <= min + lowmem_reserve)
2100         return false;

截取部分关键代码,这里在判断zone中是否有足够空闲内存时,在计算预留内存水位时会根据此申请标记为来做修改,当标记位存在时,水位值会修改为当前的一半再去判断,也就是说预留内存更少了,那么只要free大于预留内存(min + lowmem_reserve)就可以申请到内存。因而简单的换一种说法就是,当使用___GFP_HIGH申请内存时,将会更加容易申请到。

内存申请标记注意区分___GFP_HIGH和___GFP_HIGHMEM相关推荐

  1. Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别

    Table of Contents kmalloc() kzalloc() vmalloc() 总结 内核中的内存申请:kmalloc.vmalloc.kzalloc.kcalloc.get_free ...

  2. Linux brk(),mmap()系统调用源码分析3:brk()的内存申请流程

    Linux brk(),mmap()系统调用源码分析 brk()的内存申请流程 荣涛 2021年4月30日 内核版本:linux-5.10.13 注释版代码:https://github.com/Rt ...

  3. Netty 内存池(二)内存申请流程

    Netty 内存池(二)内存申请流程 上期带大家了解了一下Netty内存池都有哪些重要的对象,以及这些对象的作用是什么,本期就带大家分析一下线程是如何申请一块内存的.本期由于涉及到了很多变量和位运算, ...

  4. JVM系列二:GC策略内存申请、对象衰老

    JVM里的GC(Garbage Collection)的算法有很多种,如标记清除收集器,压缩收集器,分代收集器等等,详见HotSpot VM GC 的种类 现在比较常用的是分代收集(generatio ...

  5. C进阶指南(1):整型溢出和类型提升、内存申请和管理(转)

    转自:http://blog.jobbole.com/72830/ C语言可用于系统编程.嵌入式系统中,同时也是其他应用程序可能的实现工具之一. 当你对计算机编程怀有强烈兴趣的时候,却对C语言不感冒, ...

  6. Linux 基础知识(2)---Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别

    Linux内核空间内存申请函数kmalloc.kzalloc.vmalloc的区别 kzalloc与kmalloc区别    这个函数就是原来的两个函数的整合 , 即原来我们每次申请内存的时候都会这么 ...

  7. C/C++动态内存申请与释放

    20.1 理解指针的两种"改变" 普通变量(非指针,简单类 型变量)只能改变值:   1) int a = 100; 2) ... 3) a = 200;   第 1 行代码,声明 ...

  8. DPDK内存(二)内存申请操作

    EAL提供了一个malloc API用于申请任意大小内存. 这个API的目的是提供类似malloc的功能,以允许从hugepage中分配内存并方便应用程序移植. 通常,这些类型的分配操作不应该在数据面 ...

  9. Android内存优化(二)之Bitmap的内存申请与回收(Android N和O的对比)

    在Android O上大面积的爆了大量native Bitmap相关的泄漏问题,最大能达到几十MB,开始怀疑是出现了native内存泄漏问题,但经分析后发现是Android N和Android O在处 ...

最新文章

  1. php 缓冲区,PHP的输出缓冲区
  2. 索引使用原则-联合索引最左匹配
  3. python assert断言的用法
  4. var result = ![] == []; console.log(result); // 结果是?为什么?
  5. Chapter7-10_Deep Learning for Question Answering (1/2)
  6. Linux通过RPM方式指定软件安装目录
  7. 【Computer Organization笔记15】清华计组大作业布置:奋战二十天,做台计算机!
  8. Think in Java ---Chapter 8 多态 [基础的混凝土大厦]
  9. css中1cm等于多少px,px和rem换算(1rem等于多少px)
  10. 产品补丁包测试的基本流程
  11. ADXL361(微功耗三轴加速度计)使用笔记
  12. Stepping Number
  13. 谷歌浏览器崩溃设置崩溃_用浏览器崩溃
  14. unity如何用代码创建自已的logo
  15. 【嵌入式20】STM32F103完成对SD卡的数据读取详细操作
  16. 防近视护眼台灯哪个牌子好?无蓝光无频闪的护眼台灯推荐
  17. 用一元五角人民币兑换五分,二分和一分的硬币(每种都要有)共100枚,共有几种兑换方案,每种共兑换多少枚
  18. oracle学习笔记 Oracle体系结构概述
  19. node.js运行js_Node.js运行时v8选项列表
  20. LDN DM(SM)RGB 60 REV:1.0B 蓝牙5.2双模PCB说明

热门文章

  1. EPICS教程5 -- areaDetector模块安装
  2. 车羊问题c语言编程,再谈“羊车门”问题
  3. GameMakerStudio2调用外部dll库
  4. C语言求一元二次方程的根,这题很简单嘛?看看这种想法很惊奇!
  5. iOS NSUserDefaults删除全部记录或删除指定记录
  6. 字节跳动瞄准千亿互联网医疗蓝海,张一鸣想靠AI算法当“药神”?
  7. 硬盘开盘数据恢复-不能不学的硬盘基本知识
  8. iOS UILable换行相关设置
  9. 深圳垃圾分类告诉你这些都是什么垃圾 不仅要会分还要分的准确才行
  10. 生命苍白无力时候遇到你,即使再难也要亲手绘出五彩生活――读《平凡的世界》有感