百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

内存用的越多越好?—— 简单认识Android(Linux)的虚拟内存

gudong366 2025-05-20 22:37 11 浏览

—— 在各种帖子中,我们经常能看到类似说 "内存用的多才正常,内存就是拿来用的,搞精简剩那么多内存在那干嘛?" 的言论。这些言论或多或少缺乏严谨性。下面我会尽可能用较为简单的描述让各位对自己手机的内存管理(主要是虚拟内存)有个基本的认识,新人第一次写科普,如有错误还请各位大佬在评论区指出

—————分割线—————

注:本文中所有的"内存"均指人们常说的"运行内存"也就是"RAM"而非存储空间!

—————分割线—————

首先,我们来认识一些概念和专业名词

1.虚拟内存:

虚拟内存是现代操作系统普遍使用的一种内存管理技术,目前常用的是页式虚拟内存管理,以页(通常是4KB)为最小粒度来管理内存的分配、回收、交换等。

2.SWAP:

SWAP是虚拟内存技术的一部分,在硬盘上划分空间用于交换内存页,说人话就是把内存中的数据移动到硬盘上以腾出物理内存。Windows上也有类似的功能"分页文件"。但与Linux不同的是,Windows对分页文件是强依赖的,关掉会有大问题,详情见本文末尾的番外篇。

3.ZRAM:

ZRAM是SWAP的另一种实现,不在硬盘空间而是直接在内存中划分空间用来交换内存页,使用LZ4/ZSTD等压缩算法对内存数据进行压缩以腾出物理内存。

4.ZRAM Writeback

ZRAM Writeback是ZRAM的拓展功能,与SWAP一样会在硬盘空间上创建交换文件用于交换内存页,不同的点在于ZRAM Writeback交换的是压缩后的内存数据。写入控制逻辑运行在用户层而非内核中,具体策略由系统厂商决定,故本文不做讨论。

5.直接回收与异步回收

内存回收的两种方式,异步回收在后台线程运行,不影响当前进程,对性能和流畅度影响较小,但回收速度慢;直接回收速度快,但会阻塞当前进程,实际表现为软件界面卡住一段时间(通常很短),对性能和流畅度影响较大。

—————分割线—————

首先来回答标题的"内存用的越多越好?",这句话对吗?对,但不全对

内存确实是拿来用的,但要知道一点,要用内存的并不只有操作系统和用户的软件,还有一个大头就是文件缓存,几乎所有操作系统都有文件缓存机制,从硬盘/闪存中读取的文件会缓存在内存中,下次调用时就不需要再从硬盘/闪存读取而是直接调用文件缓存以加快速度。在内存不足时文件缓存能够被快速释放腾出内存以供分配,因此这些能够快速回收的内存与空闲内存均被内核当做"可用内存"。而你在系统后台界面和各个软件(如DEV Check)中看到的都不是"空闲内存"而是内核计算得出的"可用内存"或软件自身算法计算得出的"可用内存"。

如图在内核的meminfo中"可用内存"≠"空闲内存","空闲内存"是真正没有被任何进程或文件所占用的未分配的内存,而"可用内存"则是可用于分配的内存(其大小是一个估测值,主要由文件缓存和空闲内存中Low水位线以上的部分以及其它可快速回收的内存项决定)

所以即便你在系统后台的内存信息或各软件中看到内存还剩很多,那也并不能代表内存没得到充分利用。而搞精简搞优化的那部分人比如我追求的则是降低系统自身的内存占用,好腾出更多内存供用户应用使用,与"内存用的多才正常,内存就是拿来用的"的观点并不冲突。

—————分割线—————

进阶教程——控制内存回收与ZRAM的积极性:

在拥有ROOT权限的前提下,我们可以修改以下内核参数来控制内存回收与ZRAM的积极性。

1. vm.watermark_scale_factor:

控制内存水位线之间的间隔,调节范围为1~1000(对应0.01%至10%的总内存大小)。值太小会频繁触发直接回收导致卡顿,值太大会造成内存浪费,建议设置为100(总内存的1%)。

内核定义了min/low/high三条水位线,当空闲内存(注意是"空闲内存"而不是"可用内存")低于low水位线时内核就会唤醒kswapd异步回收内存(将数据交换至ZRAM/SWAP并回收文件缓存),直到空闲内存高于high水位线就停止;当空闲内存低于min水位线时会触发直接回收。min水位线的值由内核根据总内存大小与vm.min_free_kbytes计算比较得出,不建议修改该参数保持默认值就好。

2. vm.extra_free_kbytes:

额外保留的内存,会在min和low水位线之间增加设定的值,值太小会频繁触发直接回收导致卡顿,值太大会造成内存浪费,建议设置为总内存大小的1~2%,以KB为单位。

3. vm.swappiness:

控制内核内存不足时(低于low水位线)在交换页面至ZRAM/SWAP与回收文件缓存之间的偏向,值的范围为0~200,对于老内核范围为0~100。值越小越倾向于回收文件缓存,值越大越倾向于使用ZRAM/SWAP。

以上内核参数可在Scene中修改,也可以root权限执行以下命令修改:

echo 100 >/proc/sys/vm/watermark_scale_factor

echo 131072 >/proc/sys/vm/extra_free_kbytes

echo 100 >/proc/sys/vm/swappiness

- 如果你追求保留更多的后台,可降低extra_free_kbytes与watermark_scale_factor的值,适量增大swappiness的值。

- 如果你追求更高的流畅度,可增加extra_free_kbytes与watermark_scale_factor的值,同时将swappiness调整到较为平衡的值。

- 如果你既要又要,那就换内存更大的手机[doge]

—————分割线—————

LMK与杀后台:

从Android 9起,Google开始抛弃内核自带的LMK转为使用作为系统守护进程运行的LMKD,因此杀后台与内核本身关系就不大了,主要取决于各厂商怎么配置LMKD/引入其它杀后台机制。对于MIUI而言,除了配置LMKD外,在"电量与性能"与"framework系统框架"中均有杀后台相关代码。如果你不想用厂商额外引入的杀后台机制想自己配置LMKD,那么可用使用LSPosed模块"AppRetention"来屏蔽厂商的杀后台机制。


—————分割线—————

番外篇——有关Windows分页文件Pagefile.sys与虚拟内存地址分配的额外知识:

Windows采用两阶段内存分配(保留+提交),在提交阶段必须确保物理地址(物理内存或分页文件)的映射。分页文件作为系统提交限制的组成部分,直接决定了系统可支持的虚拟内存总量(在Windows任务管理器的内存信息卡页面上有"已提交"这个数据项,斜杠左侧是所有程序申请的内存大小之和,右侧是总虚拟内存大小,其值=物理内存大小+分页文件大小,其中分页文件由系统动态划分)

你可以简单认为在Windows上程序申请多少内存系统就会把对应大小的物理地址划分给程序,划分后其它程序就无法使用这片内存空间,而程序申请的内存大小又普遍高于其实际用到的大小,因此在关闭分页文件的情况下会出现物理内存还剩很多但打开新的程序仍提示内存不足的情况。而在Linux上则没这个问题,Linux采用延迟分配策略,仅当进程实际访问内存时才分配物理内存地址,至于程序申请的内存Linux则是分配的"真"虚拟地址,虚拟内存地址的限制则是由"vm.overcommit_memory"内核参数决定,在我们所用的Android手机上虚拟内存的分配限制"overcommit_memory"默认值为1,也就是无视虚拟内存限制允许分配全部物理内存。

在Scene的SWAP管理页面可以看到我手机上所有进程申请的内存大小高达208GB但物理内存没用完因此我还可以继续开新的软件。

至于为什么Windows不改成跟Linux一样或类似的机制那我也不知道,只能认为是Windows的历史包袱太重了(与之对应的是WIN的传奇级兼容性

相关推荐

linux sed系列 第四篇:sed工业实战——日志处理与数据清洗

“掌握了sed的编程能力后,我们如同装备精良的工匠,终于可以踏入真实的工业战场。本篇将聚焦sed在日志分析、数据合规化、多文件批处理等场景中的应用,看它如何在海量数据中游刃有余,展现文本处理的...

Linux下sed的简单使用(linux中sed是什么意思)

1、sed简介stremeditor流编辑器,它是一项Linux指令,功能同awk类似,差别在于,sed简单,对列处理的功能要差一些,awk的功能复杂,对列处理的功能比较强大,sed编辑器是一行一...

linux基础命令之date命令(linux中的date)

date命令主要用于显示或者设置系统时间语法格式:date参数对象使用date命令时,最好先使用date--help命令查看支持哪些参数,有些小型Linux系统下的date命令,只支持一些基本参...

Ubuntu linux 常用命令(ubuntu常用的50个命令)

使用dpkg命令来安装.deb包。sudodpkg-i~/example.deb如果在安装过程中遇到依赖问题,可以使用以下命令来修复:sudoapt-getinstall-f将flut...

Linux基础命令-sed命令(linux教程:sed命令的用法)

Sed全名streameditor流编辑器,它是一个强大的文本处理工具,它可以从文件中接受输入,也可以接受来自标准输入流的输入,它擅长取行。Sed的用途非常广泛,包括:1)文本替换2)选择性的输...

linux sed系列 第二篇:sed进阶技巧——地址定位与正则表达式

“上一篇我们掌握了sed的基础替换,如同获得了第一把钥匙。现在,让我们更进一步,学习如何精准锁定目标行,如同拥有了导航地图,让每一次操作都直击要害!”地址定位的四种维度sed的强大,很大程度上源...

火狐Firefox浏览器140发布:手动Unload标签页、优化翻译体验等

IT之家6月24日消息,Mozilla在发布版本139不到一个月后,推出了最新的开源网页浏览器Firefox140。新版本增加了手动Unload标签页的功能,优化了垂直标签页的调...

Linux 基本正则表达式及扩展正则表达式功能举例

在Linux中,正则表达式(RegularExpression)是一种强大的模式匹配工具,用于在文本中查找、匹配和处理特定模式的字符串。Linux支持两种类型的正则表达式:基本正则表达式(Basic...

linux下find命令的经典26个使用示例

简介find命令是基于unix的操作系统中常用的工具之一。顾名思义,它在目录层次结构中查找文件和目录。用户可以传递不同的参数,并根据文件的名称、扩展名、类型、大小、权限、修改时间、所有者、组等搜索文件...

linux运维中特殊符号的应用与实践

路径位置类的特殊符号(1)、波浪线(~)在linux系统的命令行中,~表示用户的家目录,超级用户为/root,普通用户为/home。假设我当前目录在usr/local下[root@xrylocal]...

开源框架log4cpp实战(开源gui框架)

1.Log4cpp使用Log4cpp中主要包含Category(种类),Appender(附加器),Layout(布局),Priorty(优先级),NDC(嵌套的诊断上下文)。Category、App...

Linux find命令详解(linux find -l)

一、命令介绍Linuxfind命令是类unix操作系统中最重要和最常用的命令行实用程序之一。find命令用于根据指定的条件搜索和定位与参数匹配的文件和目录列表。find命令提供了广泛的选项,允许用户...

Linux运维:单引号与双引号的使用(linux 单引号和双引号)

1、单引号的使用单引号可以将它中间的所有任意字符还原为字面意义,实现屏蔽Shell元字符的功能。注意不可以在两个单引号中间单独插入一个单引号,单引号必须成对出现。示例1:定义一个变量,并输出变量的...

Linux技巧:find 命令用法详细说明,看完会有收获

在Linux命令中,find是比较复杂难用的命令。使用该命令搜索文件时,常常发现自己找了一些例子能用,但稍微改一下条件,就搜不到想要的结果。下面会以一些实例来说明使用find命令的关键要点和...

Linux Shell中单引号、双引号、反引号的解释

1、单引号('')单引号所见即所得,直接显示单引号里的内容。即单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的。比如下面的例子,单引号所见即所得。2、双引号("...