当前位置: 首页 > news >正文

Linux - 物理内存管理 - memmap

说明

  • 裁减内核预留内存占用,在启动log中,发现memmap占用了大块内存(446个pages)。
On node 0 totalpages: 32576
memblock_alloc_try_nid: 1835008 bytes align=0x40 nid=0 from=0x0000000000000000 max_addr=0x0000000000000000 alloc_node_mem_map.constprop.0+0x4c/0xd0
memblock_reserve: [0x000000008357d000-0x000000008373cfff] memblock_alloc_range_nid+0x96/0xc2DMA32 zone: 446 pages used for memmapDMA32 zone: 0 pages reservedDMA32 zone: 32576 pages, LIFO batch:7

作用

  • 物理内存管理时,zone按固定大小划分成一个个内存页,每一个物理内存页都需要一个struct page结构来保存其元数据(状态以及使用情况等),这个结构的存储和管理机制就是memmap。
  • 每一个zone都需要拿出部分内存页来存储struct page结构体。
// file: include/linux/mm_types.h
...
struct page {unsigned long flags;            /* Atomic flags, some possibly* updated asynchronously *//** Five words (20/40 bytes) are available in this union.* WARNING: bit 0 of the first word is used for PageTail(). That* means the other users of this union MUST NOT use the bit to* avoid collision and false-positive PageTail().*/union {struct {        /* Page cache and anonymous pages *//*** @lru: Pageout list, eg. active_list protected by* pgdat->lru_lock.  Sometimes used as a generic list* by the page owner.*/struct list_head lru;/* See page-flags.h for PAGE_MAPPING_FLAGS */struct address_space *mapping;pgoff_t index;          /* Our offset within mapping. *//*** @private: Mapping-private opaque data.* Usually used for buffer_heads if PagePrivate.* Used for swp_entry_t if PageSwapCache.* Indicates order in the buddy system if PageBuddy.*/unsigned long private;};....
} _struct_page_alignment;

占用空间大小

// file: mm/page_alloc.c
static unsigned long __init calc_memmap_size(unsigned long spanned_pages, unsigned long present_pages)
{                       unsigned long pages = spanned_pages;/*                              * Provide a more accurate estimation if there are holes within* the zone and SPARSEMEM is in use. If there are holes within the* zone, each populated memory region may cost us one or two extra* memmap pages due to alignment because memmap pages for each* populated regions may not be naturally aligned on page boundary.* So the (present_pages >> 4) heuristic is a tradeoff for that.*/if (spanned_pages > present_pages + (present_pages >> 4) &&IS_ENABLED(CONFIG_SPARSEMEM))pages = present_pages;return PAGE_ALIGN(pages * sizeof(struct page)) >> PAGE_SHIFT;
}static void __init free_area_init_core(struct pglist_data *pgdat)
{enum zone_type j;int nid = pgdat->node_id;pgdat_init_internals(pgdat);pgdat->per_cpu_nodestats = &boot_nodestats;for (j = 0; j < MAX_NR_ZONES; j++) {struct zone *zone = pgdat->node_zones + j;unsigned long size, freesize, memmap_pages;unsigned long zone_start_pfn = zone->zone_start_pfn;size = zone->spanned_pages;freesize = zone->present_pages;/** Adjust freesize so that it accounts for how much memory* is used by this zone for memmap. This affects the watermark* and per-cpu initialisations*/memmap_pages = calc_memmap_size(size, freesize);if (!is_highmem_idx(j)) {       if (freesize >= memmap_pages) {freesize -= memmap_pages;if (memmap_pages)printk(KERN_DEBUG"  %s zone: %lu pages used for memmap\n",zone_names[j], memmap_pages);} elsepr_warn("  %s zone: %lu pages exceeds freesize %lu\n",zone_names[j], memmap_pages, freesize);}....}
}
  • 根据以上代码可知,memmap占用page计算公式为:
内存页对齐(管理的totalpages * struct page的size)/ 4096(页内存大小)。 
  • 根据条件(spanned_pages > present_pages + (present_pages >> 4) &&
    IS_ENABLED(CONFIG_SPARSEMEM)),totapages 可能是 zone的spanned_pages也可能是present_pages。
  • 条件(spanned_pages > present_pages + (present_pages >> 4)是考虑到导致(spanned_pages > present_pages)的内存空洞未内存页对齐而设定的折中,经验值。

spanned_pages和present_pages

  • spanned_pages 是将物理内存地址当做持续的空间计算出的page个数,没有考虑预留内存以及新技术内存热插拔导致的内存空洞。
  • present_pages 是去掉内存空洞后计算出的实际page个数。

三种内存模型

  • linux的历史上出现过三种内存模型去管理它们,依次是
  1. 平坦内存模型(flat memory model)
  2. 不连续内存模型 (discontiguous memory model)
  3. 稀疏内存模型(sparse memory model)。
  • 提出新的内存模型是因为老的内存模型已不适应计算机硬件的新技术(例如:NUMA技术、内存热插拔等),主要的原因是:老模型未考虑到内存空洞。
  • 内存模型的设计则主要是权衡以下两点(空间与时间):
  1. 尽量少的消耗内存去管理众多的struct page。
  2. pfn_to_page和page_to_pfn的转换效率。

FLATMEM (flat memory model)

  • FLATMEM内存模型是Linux最早使用的内存模型,那时计算机的内存通常不大需求也很单一,不需要考虑热插拔等导致内存空洞的因素。
  • Linux会使用一个struct page mem_map[x]的数组根据PFN去依次存放所有的strcut page,且mem_map也位于内核空间的线性映射区,所以根据PFN(页帧号)即可轻松的找到目标页帧的strcut page。
  • FLATMEM模型是非常简单可靠的机制,但是最大的问题就是未考虑内存空洞,而导致内存浪费。

DISCONTIGMEM (discontiguous memory model)

  • DISCONTIGMEM的意思是不连续内存模型,解决的就是FLATMEM未考虑的内存空洞问题,但是其是非常短命的内存模型,很快被后续的SPARSEMEM完全替代。
  • 注意:较新版本的Linux内核配置中没有该选项。

SPARSEMEM (sparse memory model)

  • SPARSEMEM(稀疏内存模型)是当前内核默认的选择,从2005年被提出后沿用至今,但中间经过几次优化,包括:CONFIG_SPARSEMEM_VMEMMAP和CONFIG_SPARSEMEM_EXTREME的引入,这两个配置通常是被打开的。
  • 主要解决的问题:
  1. 可以解决内存空洞导致的内存浪费。
  2. 支持内存的热插拔(memory hotplug)。
  3. 支持nodes间的overlap。
  • 技术原理待研究。

减小memmap内存占用

  • 回到最初的目标:裁减memmap内存占用,思路如下:
  1. 减少totoal page
  • 将预留内存(reserved memory)从total page中排除(no-map)
  1. 裁减struct page结构体
  • 由于对细节的了解不够以及内存占用会做页对齐,裁减较小,对齐后,也看不到太多效果。

减少totoal page

  • 使用no-map将预留内存从total page中排除,但是由于嵌入式平台使用的是FLATMEM模型,没有效果。
  • 修改内核配置,将内存模型改为Sparse模型:
Memory Management options  ---> Memory model (Sparse Memory)  --->                           [] Flat Memory[] Sparse Memory
  • 实测后发现memmap占用确实降了,只需要440个page,如下:
On node 0 totalpages: 32126DMA32 zone: 440 pages used for memmapDMA32 zone: 0 pages reservedDMA32 zone: 32126 pages, LIFO batch:7
  • 但是总的预留内存size增大了很多,如下:
// Flat memory
Memory: 48032K/130304K available (3478K kernel code, 500K rwdata, 1504K rodata, 124K init, 212K bss, 82272K reserved, 0K cma-reserved)
// Sparse memory
Memory: 31636K/128504K available (3474K kernel code, 499K rwdata, 1505K rodata, 128K init, 212K bss, 96868K reserved, 0K cma-reserved)
  • 开启memblock debug,log如下,确认Sparse相对于Flat模型会占用大量内存(16~18MB),因此对于嵌入式平台,使用Sparse模型得不偿失。
memblock_alloc_try_nid: 16777216 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 sparse_init+0xce/0x1d4
memblock_reserve: [0x0000000081dcd000-0x0000000082dccfff] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 4096 bytes align=0x40 nid=0 from=0x0000000000000000 max_addr=0x0000000000000000 sparse_index_alloc+0x42/0x64
memblock_reserve: [0x000000008373c000-0x000000008373cfff] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 40 bytes align=0x40 nid=0 from=0x0000000000000000 max_addr=0x0000000000000000 sparse_init_nid+0x3e/0x1a2
memblock_reserve: [0x000000008373bfc0-0x000000008373bfe7] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_exact_nid_raw: 2097152 bytes align=0x200000 nid=0 from=0x0000000080000000 max_addr=0x0000000000000000 sparse_init_nid+0xc4/0x1a2
memblock_reserve: [0x0000000083400000-0x00000000835fffff] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid_raw: 4096 bytes align=0x1000 nid=0 from=0x0000000080000000 max_addr=0x0000000000000000 vmemmap_pud_populate+0x16/0x4a
memblock_reserve: [0x000000008373a000-0x000000008373afff] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid_raw: 4096 bytes align=0x1000 nid=0 from=0x0000000080000000 max_addr=0x0000000000000000 vmemmap_pmd_populate+0x3a/0x6c
memblock_reserve: [0x0000000083739000-0x0000000083739fff] memblock_alloc_range_nid+0x96/0xc2
memblock_free: [0x00000000835c0000-0x00000000835fffff] sparse_init_nid+0x116/0x1a2
  • 其它优化思路:将预留内存从total pages中排除,不采用no-map方式,采用其它方式,将排除后的内存段告诉内核(修改dts中memory大小)。

相关文章:

Linux - 物理内存管理 - memmap

说明 裁减内核预留内存占用&#xff0c;在启动log中&#xff0c;发现memmap占用了大块内存&#xff08;446个pages&#xff09;。 On node 0 totalpages: 32576 memblock_alloc_try_nid: 1835008 bytes align0x40 nid0 from0x0000000000000000 max_addr0x0000000000000000 al…...

Python爬虫动态ip代理防止被封的方法

目录 前言 一、什么是动态IP代理&#xff1f; 二、如何获取代理IP&#xff1f; 1. 付费代理IP 2. 免费代理IP 3. 自建代理IP池 三、如何使用代理IP爬取数据&#xff1f; 1. 使用requests库设置代理IP 2. 使用urllib库设置代理IP 3. 使用selenium库设置代理IP 四、常…...

01Urllib

1.什么是互联网爬虫&#xff1f; 如果我们把互联网比作一张大的蜘蛛网&#xff0c;那一台计算机上的数据便是蜘蛛网上的一个猎物&#xff0c;而爬虫程序就是一只小蜘蛛&#xff0c;沿着蜘蛛网抓取自己想要的数据 解释1&#xff1a;通过一个程序&#xff0c;根据Url(http://www.…...

python爬取酷我音乐 根据歌名进行爬取

# _*_ coding:utf-8 _*_ # 开发工具:PyCharm # 公众号:小宇教程import urllib.parse from urllib.request import urlopen import json import time import sys import osdef Time_1...

【深度学习】吴恩达课程笔记(五)——超参数调试、batch norm、Softmax 回归

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【吴恩达课程笔记专栏】 【深度学习】吴恩达课程笔记(一)——深度学习概论、神经网络基础 【深度学习】吴恩达课程笔记(二)——浅层神经网络、深层神经网络 【深度学习】吴恩达课程笔记(三)——参数VS超参数、深度…...

腾讯云轻量级服务器和云服务器什么区别?轻量服务器是干什么用的

随着互联网的迅速发展&#xff0c;服务器成为了许多人必备的工具。然而&#xff0c;面对众多的服务器选择&#xff0c;我们常常会陷入纠结之中。在这篇文章中&#xff0c;我们将探讨轻量服务器和标准云服务器的区别&#xff0c;帮助您选择最适合自己需求的服务器。 腾讯云双十…...

解决:虚拟机远程连接失败

问题 使用FinalShell远程连接虚拟机的时候连接不上 发现 虚拟机用的VMware&#xff0c;Linux发行版是CentOs 7&#xff0c;发现在虚拟机中使用ping www.baidu.com是成功的&#xff0c;但是使用FinalShell远程连接不上虚拟机&#xff0c;本地网络也ping不通虚拟机&#xff0c…...

SpringBoot项目集成发邮件功能

1&#xff1a;引入依赖2&#xff1a;配置设置3&#xff1a;授权码获取&#xff1a;4&#xff1a;核心代码5&#xff1a;postman模拟验证6&#xff1a;安全注意 1&#xff1a;引入依赖 <dependency><groupId>org.apache.commons</groupId><artifactId>c…...

【Spring篇】使用注解进行开发

&#x1f38a;专栏【Spring】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 &#x1f970;欢迎并且感谢大家指出小吉的问题 文章目录 &#x1f33a;原代码&#xff08;无注解&#xff09;&#x1f384;加上注解⭐两个注…...

Flink(六)【DataFrame 转换算子(下)】

前言 今天学习剩下的转换算子&#xff1a;分区、分流、合流。 每天出来自学是一件孤独又充实的事情&#xff0c;希望多年以后回望自己的大学生活&#xff0c;不会因为自己的懒惰与懈怠而悔恨。 回答之所以起到了作用&#xff0c;原因是他们自己很努力。 …...

【2023春李宏毅机器学习】生成式学习的两种策略

文章目录 1 各个击破2 一步到位3 两种策略的对比 生成式学习的两种策略&#xff1a;各个击破、一步到位 对于文本生成&#xff1a;把每一个生成的元素称为token&#xff0c;中文当中token指的是字&#xff0c;英文中的token指的是word piece。比如对于unbreakable&#xff0c;他…...

Android13 adb 无法连接?

Android13 adb 无法连接? 文章目录 Android13 adb 无法连接?一、前言二、替换adbGoogle 官网对adb的介绍&#xff1a;Google 提供的adb tools的下载&#xff1a; 三、总结1、adb connect 连接后显示offline2、输入adb devices 报错&#xff1a;版本不匹配导致3、adb常用命令4…...

Ubuntu 20.04 调整交换分区大小

Ubuntu 调整交换分区大小 一、系统情况二、去除旧的交换分区文件三、配置并启用交换分区四、查看swap文件大小 一、系统情况 Ubuntu &#xff1a;Ubuntu 20.04.6 LTS 交换分区位置&#xff1a; cat /proc/swaps二、去除旧的交换分区文件 去掉旧的交换分区有两个步骤&#x…...

将Agent技术的灵活性引入RPA,清华等发布自动化智能体ProAgent

近日&#xff0c;来自清华大学的研究人员联合面壁智能、中国人民大学、MIT、CMU 等机构共同发布了新一代流程自动化范式 “智能体流程自动化” Agentic Process Automation&#xff08;APA&#xff09;&#xff0c;结合大模型智能体帮助人类进行工作流构建&#xff0c;并让智能…...

高济健康:数字化科技创新与新零售碰撞 助推医疗产业优化升级

近日&#xff0c;第六届中国国际进口博览会在上海圆满落幕&#xff0c;首次亮相的高济健康作为一家专注大健康领域的疾病和健康管理公司&#xff0c;在本届进博会上向业内外展示了围绕“15分钟步行健康生活圈”构建进行的全域数字化升级成果。高济健康通过数字化科技创新与新零…...

SystemVerilog学习 (5)——接口

一、概述 验证一个设计需要经过几个步骤&#xff1a; 生成输入激励捕获输出响应决定对错和衡量进度 但是&#xff0c;我们首先需要一个合适的测试平台&#xff0c;并将它连接到设计上。 测试平台包裹着设计,发送激励并且捕获设计的输出。测试平台组成了设计周围的“真实世界”,…...

vue3插槽的使用

什么是插槽 Vue 3 插槽&#xff08;Slots&#xff09;是一个强大的工具&#xff0c;用于在组件之间传递内容和逻辑。通过使用插槽&#xff0c;我们可以将子组件中的内容插入到父组件中的特定位置。本篇文章将总结 Vue 3 插槽的基本用法、特点以及使用场景。 基本用法 插槽分为…...

IPTABLES问题:DNAT下如何解决内网访问内部服务器问题

这个问题&#xff0c;困扰了我几年了&#xff0c;今天终于得到解决。 问题是这样的&#xff0c;在局域网内部有一台服务器&#xff0c;通过IPTABLES的网关提供对外服务&#xff0c;做过IPTABLES网关的人都知道&#xff0c;这很容易做到&#xff0c;只要在网关机器上写一个DNAT…...

异步任务线程池——最优雅的方式创建异步任务

对于刚刚从校园出来的菜鸡选手很容易写出自以为没问题的屎山代码&#xff0c;可是当上线后就会立即暴露出问题&#xff0c;这说到底还是基础不够扎实&#xff01;只会背八股文&#xff0c;却不理解&#xff0c;面试头头是道&#xff0c;一旦落地就啥也不是。此处&#xff0c;抛…...

uniapp 跨页面传值及跨页面方法调用

uniapp 跨页面传值及跨页面方法调用 1、跨页面传值 使用全局方法监听uni.$emit、uni.$on、uni.$off 发布、监听、移除 methods: {addFun(){let data [1]uni.navigateBack({ // 返回上一页delta: 1})uni.$emit(successFun,{data}) // 传值} }监听页 onLoad() {uni.$on(succ…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

node.js的初步学习

那什么是node.js呢&#xff1f; 和JavaScript又是什么关系呢&#xff1f; node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说&#xff0c; 需要在node.js的环境上进行当JavaScript作为前端开发语言来说&#xff0c;需要在浏览器的环境上进行 Node.js 可…...

拟合问题处理

在机器学习中&#xff0c;核心任务通常围绕模型训练和性能提升展开&#xff0c;但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正&#xff1a; 一、机器学习的核心任务框架 机…...

Element-Plus:popconfirm与tooltip一起使用不生效?

你们好&#xff0c;我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip&#xff0c;产品要求是两个需要结合一起使用&#xff0c;也就是鼠标悬浮上去有提示文字&#xff0c;并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...

Spring Boot 中实现 HTTPS 加密通信及常见问题排查指南

Spring Boot 中实现 HTTPS 加密通信及常见问题排查指南 在金融行业安全审计中&#xff0c;未启用HTTPS的Web应用被列为高危漏洞。通过正确配置HTTPS&#xff0c;可将中间人攻击风险降低98%——本文将全面解析Spring Boot中HTTPS的实现方案与实战避坑指南。 一、HTTPS 核心原理与…...

RabbitMQ work模型

Work 模型是 RabbitMQ 最基础的消息处理模式&#xff0c;核心思想是 ​​多个消费者竞争消费同一个队列中的消息​​&#xff0c;适用于任务分发和负载均衡场景。同一个消息只会被一个消费者处理。 当一个消息队列绑定了多个消费者&#xff0c;每个消息消费的个数都是平摊的&a…...