LWN: 用DMEMFS来更高效地管理部分内存!

1.2 ESP32-MicroPython基础操作 用五篇文章,描述如何使用ESP32在MicroPython固件下,开发一个支持Modbus采集,MQTT上报,可OTA升级的IOT协议采集器。这是第一篇,基础操作。 阅读详情

关注了就能看到更多这么棒的文章哦~

Sidestepping kernel memory management with DMEMFS

By Jonathan Corbet
December 7, 2020
DeepL assisted translation
https://lwn.net/Articles/839216/

内核的主要工作之一就是管理系统所拥有的内存。不过多年来,出于各种原因,有时候需要把系统一部分内存隐藏起来,让内核看不到。现在又出来一个最新的原因,来自一个叫做 DMEMFS 的机制,提出这个机制是希望绕过内核跟踪 RAM 过程中的一些低效率做法。

从前,人们把内存隐藏起来让内核看不到,主要是为了避免内存碎片化的相关问题。在系统运行一段时间后,几乎不可能分配得出大块连续区域,这就给那些必须要这种大块连续内存的 device 带来了麻烦。当时,有一个叫做 "bigphysarea "的 patch,一直没有合入 kernel,主要就是用来为这种大块连续的内存分配来预先 reserve 一块内存区域。由于内核没有直接接触到这些内存,所以它无法对其进行操作,也就不会有碎片化问题。LWN 第一次介绍 bigphysarea 是在 1999 年,但当时这个 patch 已经存在一段时间了。

后来(2010 年),contiguous memory allocator(CMA)patch 使用同样的技术提供了类似的功能。不过从那时起,分配大块连续区域的需求已经变小了很多。内核本身的碎片整理机制已经有了很大的改进,并且大多数设备也都安装了更多的内存。CMA 现在依靠 compaction 机制(https://lwn.net/Articles/486301/) ,不再预先挖掉一块内存保留下来专用了。

DMEMFS 的动机则不同。内核通过一个叫做 "memory map" 的数据结构来跟踪内存,它本质上是一组 page strcuture 的数组。有大量信息放在这个结构中,用来告知内核每个 page 是如何使用的、跟踪它在各种 list 中的位置、也用来将它与真正的 backing store 对应起来,等等。多年来,我们已经花费了很多努力来保持 struct page 尽可能的小,但在 64 位系统中,它仍然占据了 64 个字节。

这个 size 看起来似乎并不是很大,但是,一般的 page 本身大小仅仅为 4KB,在现代的系统中,会有很多的 struct page。一台安装了 16GB 的笔记本电脑会有 4194304 个页面,也就是说,光是跟踪这些内存就用了 256MB 的内存。在笔记本上损失这么多内存或许是可以忍受的,但在其他一些环境下,就无法接受了。在 patch 相关的邮件中,作者 Yulei Zhang 指出,一个提供虚拟主机托管的服务商(hosting provider),如果一台机器安装了 320GB 的内存,就会因为 page structure 而损失 5GB 的内存。如果能够回收这些内存,服务提供商就可以将更多的 guest 塞进这台机器,增加每台服务器带来的收入,而这个指标是托管提供商非常重视的。

如上所述,DMEMFS 的工作原理是在启动时分出一部分系统内存,具体数量由 dmem= 这样的命令行参数控制。系统中每个 NUMA 节点上都需要按照这个指定数值来预留相应的内存。如果这个数量以"!"开头,意思就反过来,相当于指定 DMEMFS 要给内核留多少内存,而把其余的内存都分给 DMEMFS。一旦系统启动,可以通过挂载 dmemfs 文件系统并创建若干个(一个也行)所需大小的文件来分配这部分内存。调用 mmap() 来把内存映射到进程的地址空间。一个 dmemfs 文件也可以交给 QEMU 作为 guest machine 的内存空间(backing store)。这块内存区域也支持 NUMA policy,也可以提供 huge page,用起来就跟普通内存一样。

也许对于那些迫切需要充分利用内存、而且不需要内核来实际管理内存的场景来说,DMEMFS 是最好的解决方案。但这是一个由 37 个 patch 组成的改动,增加了 3400 多行代码,专门用于把内存资源管理这个工作从 kernel 中切割出来。每当出现这样巨大改动的情况时,都应该思考一下问题的根源,以及是否可能存在其他的解决方案。

早在 1991 年,当第一个 Linux 内核发布的时候,当时的机器内存比现在还少。当初的这个 PC 广告 (https://books.google.com/books?id=WVAEAAAAMBAJ&lpg=PA1&dq=infoworld&pg=PT73&hl=en#v=onepage&q&f=false) 很有启发意义,一个高端系统的特点是 4MB 的内存,价格仅为 3700 元,这是 1991 年。该系统使用了 4KB 的页面,所以总共有 1024 个页面供内核管理。当时大多数个人电脑系统的内存都比这个少。

当代的计算机内存空间已经相当大了,但 page size 仍然是 4KB,所以内核管理的 page 数量增加了三个数量级了。page struct 的数量也相应增加了。这些 struct 自己也变大了,主要是因为向 64 位处理器过渡导致 struct page 的大小大幅增加。很明显,size 增加会带来副作用,但是与此同时,page structure 的数量增加也导致内核中许多地方的开销变大。

一个可能的解决方法是增加内核管理的 page size,如果需要的话,可以将多个物理页面聚集成较大的一组来作为管理单位。现在一些架构也支持使用更大的 page size,例如 arm64 内核可以使用 64KB 的页面大小。多年来,许多开发者试图在内核中实现某种通用的页面集群(generalized page clustering),但这些工作都没能进入 mainline。没有合入的原因之一是这些改动都比较复杂,但这不是唯一的因素。

使用更大的 page size 会导致的另一个问题就是内部碎片,从而只需要使用少量内存的时候,由于必须分配一个完整的 page 从而导致浪费内存。一个典型的例子就是小文件所对应的 page cache。一个单行的 shell 脚本可能只需要不到 100 个字节,但它仍然需要在 page cache 中分配一个完整的 page。超过这 100 个字节的区域都被浪费了,使用的 page size 越大,显然浪费的就会越多。几十年前的大家的经验都是:Unix 系统上的大多数文件都很小。虽然现在这个说法可能不像以前那样典型了。

编者不知道有没有什么研究是认真地测量了真实世界的系统上如果使用更大的 page size 的话,因为 internal fragmentation 而会导致损失多少内存,但这种担心使得这类 patch 无论如何也很难被接受并合并入 mainline。目前,最接近的工作可能是 Matthew Wilcox 的 "large pages in the page cache" ,这个工作是在更高层次实现的,并不会减少系统中 page struct 的数量。

因此,DMEMFS 的补丁可能需要合并,原因很简单,现在这组 patch 已经能正常工作了。但很可能这个问题的真正解决方案并不是这组 patch。与其从内核中隐藏页面,不如通过以更大块的方式来处理内存来减少内核内部的开销。目前看来,不断增加的内存大小最终会迫使人们做出这种改变。而事实证明,这么多年来内存大小一直在不断增长。在改变内核以更有效的方式处理内存之前,我们可能别无选择,只能合入这类将 kernel 排除在内存分配决策之外的改动了。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

Linux内存管理(13):paging_init 详解 从memblock初始化一文中得知在调用之前,存放 Kernel Image 和DTB 两端物理内存区域可以访问 (相应的页表已经建立好)。在 memblock 初始化之后,物理内存已经添加到系统,但是这部分的物理内存到虚拟内存的映射还没有建立,可以通过 memblock_alloc() 分配一段物理内存,但是无法访问,一切还需要等待之后,建立最终的页表,从而实现物理内存到虚拟内存的映射。VA_BITS=39, PAGE_SHIFT=12(每页4K)本文重点剖析了。 阅读详情

相关推荐

单条16g和双条8g哪个好

对于CPU性能较高的用户,建议使用16G内存,因为内存大可以预加载更多东西,速度更快,同时多任务切换更流畅。双通道内存可以同时输出和输入,带宽翻倍,提高临时数据的传输速度,显著改善吃内存的程序。•对于普通使用电脑的人群与热衷于玩游戏的玩家来说,购买单通道16GB就已足够,而且单通道16GB的价格要低于双通道16GB,性价比更高。若支持32g,那么2条16g的值得,也是说单条16g日后添加是个选择方式。•单条16g内存的价格比双条8g内存的价格低,而且16g的内存容量大,一条内存十分的方便。

欢乐打代码! 5434

tab点击切换,简单实例

<template> <div class=" padding-50 tabchange" style="color:yellow;"> <ul class="title-ul clearfix"> <li class="title-lists active">tab1</li> <li class="title-lists ">tab2</li>

LJ_QWE的博客 852

实战指南:基于ELK与Grafana构建天融信防火墙日志可视化看板

本文详细介绍了如何基于ELK与Grafana构建天融信防火墙日志可视化看板,包括环境准备、日志收集与解析配置、Elasticsearch存储优化、Grafana看板设计等关键步骤。通过实战案例和优化技巧,帮助用户高效处理天融信防火墙日志,实现安全态势的可视化监控与分析。

weixin_34246529的博客 226

Linux内存管理(四):paging_init分析

上文介绍了启动页表的创建,通过fix map建立DTB物理地址的映射,以及memblock管理物理内存。现在我们能够通过memblock进行物理内存的分配,但分配的内存还不能够进行访问,我们需要对memblock管理的内存进行映射,这就是paging_init的一部分工作 paging_init void __init paging_init(void) { pgd_t *pgdp = pgd_set_fixmap(__pa_symbol(swapper_pg_dir)); -------- (1

Hober 6175

银河麒麟V10安装docker

最近在做的一个信创项目使用的操作系统是银河麒麟高级服务器V10,在安装docker时,会遇到下面的错误。 nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.0-3.el7.x86_64 经过分析,以下依赖包是centos系统中的包,所以需要给kylinos创建一个合适的centos源。经过实验,Kylin Linux Advanced Server V1

m0_38004228的博客 4907

Visual Studio Community与Visual Studio Community与VS Code有啥区别

Visual Studio Code提供了基本的代码编辑、调试和版本控制功能,以及丰富的插件和扩展库。Visual Studio Community和Visual Studio Code在功能上有很大的差异,Visual Studio Community提供了比Visual Studio Code更多的功能,包括代码重构、智能提示、图形化设计等。他的优势在于它的轻量级和灵活性。此外,Visual Studio Code还具有丰富的扩展和插件生态系统,用户可以通过安装插件来扩展其功能,从而满足自己的需求。

m0_56551554的博客 2843

LWN: 节省huge page场景下的struct page内存占用!

关注了就能看到更多这么棒的文章哦~Reducing page structures for huge pagesBy Jonathan CorbetDecember 11, 2020De...

Linux News搬运工 485

【胡学长 带你学 Global Mapper 】如何将影像地图转换为国家2000坐标系

多部门联合开展工作坐标数据不匹配怎么办?Hi,我是胡学长!今天教大家如何利用Global Mapper将谷歌影像数据转换为国家2000坐标系影像数据 。

一起来交流学习吧 1万+

内存映射过程之paging_init

内存映射过程之paging_init 导读 之前已经逐步整理完成了idmap、fixup、memblock等内容,在此阶段已经可以: 访问kernel image的地址空间; 访问FDT地址空间,即已经获取device tree相关数据; 可以通过memblock提供的接口申请内存; 则接下来需要做的处理,是要把从fdt中获取的mem layout关系建立实际的映射; 所谓建立映射,实质很简单,即根据页表大小和地址空间大小,填充PUD PMD PTE等数据; 1. 页表转换关系 这部分之前已经整理过了,

And乔的博客 1778

SigFit实战:从FEA到光学仿真的热力耦合分析全流程解析

在光机系统与芯片封装等精密工程领域,热与力的耦合效应是影响产品性能与可靠性的核心物理问题。有限元分析(FEA)是预测结构在热、力载荷下变形与应力的基础工具,但其结果通常无法直接用于评估光学性能。这需要一座桥梁,将物理场数据转化为光学设计语言。其核心原理在于数据映射与面形表征技术,例如通过泽尼克多项式拟合,将离散的节点位移分解为离焦、像散等标准光学像差。这项技术的工程价值在于,它实现了多物理场仿真的闭环,使工程师能在设计阶段精准预测热变形或应力对波前误差、调制传递函数等关键光学指标的影响。其典型应用场景包括高

weixin_28630185的博客 336

R语言 Chow Test

Chow 测试用于测试不同数据集上的两个不同回归模型中的系数是否相等。 该测试通常用于计量经济学领域,使用时间序列数据来确定数据在某个时间点是否存在结构性中断。 本教程提供了如何在 R 中执行 Chow 测试的分步示例 首先,我们将创建一些假数据: #create data data <- data.frame(x = c(1, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13,

Mrrunsen的博客 1946

Java中的OutOfMemoryError的各种情况及解决和JVM内存结构

在JVM中内存一共有3种:Heap(堆内存),Non-Heap(非堆内存) [3]和Native(本地内存)。 [1] 堆内存是运行时分配所有类实例和数组的一块内存区域。非堆内存包含方法区和JVM内部处理或优化所需的内存,存放有类结构(如运行时常量池、字段及方法结构,以及方法和构造函数代码)。本地内存是由操作系统管理的虚拟内存。当一个应用内存不足时就会抛出java.lang.OutOfMemoryError 异常。 [1] 问题 表象 诊断工具

srs1995的博客 1089

汽车行业OTD业务模式入门学习

本文是在学习彭俊松老师的《汽车行业整车订单交付系统》后,对于OTD理解的一些摘录,供诸位参考学习。

qq_40664711的博客 1万+

ESP32_FreeRtos_内存使用情况查看

ESP32_FreeRtos_内存使用情况查看 前言:之前项目用到了esp8266也是用的freertos,当时也想查看内存使用情况,可是搞了好久也没有成功,只得暂时先放弃,如今使用esp32开发时也需要查看内存使用情况,主要是跑一下测试监控内存的变化,防止内存泄漏。 1、使用make menuconfig打开一个功能 2、方法一——查看每个任务剩余内存 3、方法二——查看每个任务内存使用率更加直观 4、分析之前esp8266没有成功的原因 首先要打开这项功能 方法一 //首先创建一个任务单独来做

会选科技的博客 6909

R语言中5种正态性检验的方法

统计学中的t检验和方差分析等方法的应用条件是样本都来自正态总体或近似正态总体,只有符合这个条件,才能用这些方法来检验各样本所属的总体参数的差异显著性。文本向大家介绍在R语言中检验正态性的几种方法: 1、Kolmogorov-Smirnov检验 K-S检验检验单一样本是否来自某一特定分布。比如检验一组数据是否为正态分布。它的检验方法是以样本数据的累积频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。K-S检验的原假设和备择假设为: H0:样本所来自的总体分布服从

Mrrunsen的博客 2万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

linux内存管理——内存初始化3---paging_init

从Linux内存管理之物理内存初始化中,可知在paging_init调用之前,存放Kernel Image和DTB的两段物理内存区域可以访问了(相应的页表已经建立好)。尽管物理内存已经通过memblock_add添加进系统,但是这部分的物理内存到虚拟内存的映射还没有建立,可以通过memblock_alloc分配一段物理内存,但是还不能访问,一切还需要等待paging_init的执行。最终页表建立好后,可以通过虚拟地址去访问最终的物理地址了。

枫潇潇 1478

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Linux内存管理 paging_init解析

从(二)Linux物理内存初始化中,可知在调用之前,存放和DTB的两段物理内存区域可以访问了(相应的页表已经建立好)。尽管物理内存已经通过添加进系统,但是这部分的物理内存到虚拟内存的映射还没有建立,可以通过分配一段物理内存,但是还不能访问,一切还需要等待的执行。最终页表建立好后,可以通过虚拟地址去访问最终的物理地址了。按照惯例,先上图,来一张ARM64内核的内存布局图片吧,最终的布局如下所示:开启探索之旅吧!

生活需要深度 1084

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Linux 内存管理窥探(8):内存初始化(paging_init)

参考文档: https://github.com/gatieme/LDD-LinuxDeviceDrivers/tree/master/study/kernel/02-memory/03-initialize/04-bootmem_init 感谢作者的无私分享。 我们住关注 start_kernel 中关于内存管理的部分总览: asmlinkage __visible void __i...

StephenZhou 2471

内存管理基础学习笔记 - 1. 概述

目录1. 前言2. 回顾说明地址空间映射内存管理启动部分 1. 前言 本专题文章承接之前《kernel启动流程-start_kernel的执行》专题文章,本专题我们开始学习内存管理部分,本文是概述部分。 kernel版本:5.10 平台:arm64 2. 回顾说明 地址空间映射 在《kernel启动流程-start_kernel的执行_2.setup_arch》我们已经看到如下图的地址空间映射: 也即是说在内存初始化阶段已经为物理地址空间创建了映射关系,包括memblock.memory区域,kernel

HZero 1381

【ESP32-IDF】03-1 系统-内存管理

ESP32内存结构 文章目录ESP32内存结构1. 内存分段2. ESP32 内存模型2.1 片内RAM2.1.1 片内RAM空间布局2.1.2 IRAM组织结构2.1.3 DRAM2.1.4 启用蓝牙之后的DRAM2.1.5 启用跟踪调试空间之后 DRAM 组织结构2.2 片外RAM2.2.1 PSRAM (也叫SPIRAM)3. ESP32 内存的使用3.1 IRAM3.2 IROM3.3 RTC快速内存3.4 DRAM3.5 DROM3.6 RTC慢速内存3.7 DMA4. 堆的分配与调试4.1 相关

qq_41741344的博客 8503

esp32查询剩余内存_esp32 内存优化 --各个优化

内存优化ESP32 内部 SRAM 有 520KB,但是系统启动后可用内存约为 300KB(以Hello World工程为例),很多物联网应用都会使用 Wi-Fi 连接云端/ Bluetooth 和手机通信/ OTA 升级等功能,可能会面临内存不足问题。尽管 ESP32 可以外挂 PSRAM,为了节省成本,可以不使用 PSRAM 当然最佳。优化措施1 修改 SPI RAM config2 修改...

weixin_39890327的博客 5310

参考 | 辨别真假笔记本三星内存条 (ddr4)

辨别海鲜市场真假三星内存条

JackyAce6880的博客 2万+

Linux内存管理之内核分页机制(paging_init)初始化

背景 前面分析了kernel boot阶段内存管理实现的分段机制,可以发现页表描述符是按照ARM MMU硬件页表转换逻辑来设计的。kernel在初始化过程中只映射了内核 image部分的物理内存,在某个合适的时候内核需要将尽可能多的物理内存映射到页表中。 Linux设计为通用的操作系统,为了便于移植需要抽象出一些硬件细节,我们在驱动代码中看到大量的core层代码就是这个思想的体现。内核中只有和...

月出皎兮。 佼人僚兮。 舒窈纠兮。 劳心悄兮。 3053

内存条趋势

截至2026年4月10日,一根16GB DDR4内存条的市场价格,取决于你通过什么渠道购买:现货市场(如华强北、电商零售):价格在 689元 至 759元 之间-2-4-10。合约市场(品牌新机采购价):价格在 900元 左右,且预计下季度还会上涨-1-6。为了让你更直观地感受涨幅,我把这轮涨跌的几个关键节点整理了一下:以今天(2026年4月10日)的价格来看:相较于2025年4月的涨价前水平(200元):上涨了约 489元至559元,涨幅高达 244% 至 279%。一句话总结:现在的价格是涨价前的近3.

hxsln11的博客 6861

linux内存访问和页表建立,linux内存管理笔记(十二)----准备页表

Linux是为通用的操作系统而设计,为了便于移植需要抽象出一些硬件细节,在驱动代码中看到大量的抽象层的思想。内核中只有和硬件相关的代码才会单独实现,这样做便于移植和添加新硬件。内核里所有进程和内核线程都共享1GB的地址空间,而每个应用程序对应的进程都有独立的3GB的地址空间,相互不干扰用户空间:在Linux中,每个用户进程都可以访问4GB的线性地址空间,从0到3GB的虚拟地址空间是用户空间,每个用...

weixin_42522320的博客 539

内存条的构造、原理及性能参数

内存条是电脑中用来暂时存储和访问数据的部件。它就像是一个“飞毛腿快递小哥”,快速、准确地把数据从大仓库“硬盘”送到用户"CPU"手中。假如没有内存,就算CPU跑冒烟,电脑也快不起来。现在的内存条,容量普遍比较大,动不动十好几G,所以被诅咒的时候少了。想当年,在那个256MB、512MB的年代,打开个大一点儿的程序经常会卡得你痛不欲生。今天就说说内存条的构造和原理。

jjmhx的专栏 5059
上一篇: LWN: XFS以及稳定内核发布!
下一篇: LWN:32位Linux的未来!
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值