内存基础概念:从VSS到USS,你真的懂内存吗?
大家好,我是老张。做移动端性能优化这么多年,我见过太多开发同学一提到内存就头疼。说实话,我刚入行那会儿也踩过不少坑。今天咱们就来聊聊内存的那些基础概念,把这些搞明白了,后面的瘦身技巧才能用得上。
什么是内存占用?
先问个问题:你打开一个App,它到底占了多少内存?
很多人会直接看任务管理器里的数字。但那个数字其实很「虚」。为什么?因为内存占用不是单一数值,它分好几种统计口径。
简单来说,内存占用就是你的App在运行时,从系统那里「借」来存放数据的地方。这些数据包括代码、变量、图片、缓存等等。你想想看,一个App要跑起来,总得有个地方放这些东西吧?
核心观点:内存占用不是「用了多少」,而是「系统认为你用了多少」。这两个概念差别很大。
VSS/RSS/PSS/USS的区别
好,重点来了。这四个缩写,我建议你背下来。我在项目中遇到过好几次,团队里有人把RSS当成实际内存占用,结果优化方向全错了。
| 指标 | 全称 | 含义 | 典型场景 |
|---|---|---|---|
| VSS | Virtual Set Size | 虚拟内存占用 | 基本不看,太虚 |
| RSS | Resident Set Size | 常驻内存占用 | 包含共享库,容易高估 |
| PSS | Proportional Set Size | 比例分摊内存 | 最接近真实占用 |
| USS | Unique Set Size | 独占内存 | 进程独享,不共享 |
VSS:最虚的那个
VSS是虚拟内存大小。说白了,就是你的进程「声称」自己需要多少内存。但它并不真实占用物理内存。比如你malloc了1GB空间,但只用了1KB,VSS就是1GB。这个值基本没有参考价值,我一般直接忽略它。
RSS:容易误导人
RSS是实际驻留在物理内存中的大小。但它有个问题——它把共享库的内存也算进去了。比如两个App都用了同一个系统库,RSS会把这份内存算两次。你想想看,这明显不合理吧?
注意:用RSS来评估单个App的内存占用,结果通常会偏高。我曾经见过一个项目,用RSS监控内存,结果发现「内存泄漏」了50MB,最后查出来是共享库被重复计算了。
PSS:我最常用的指标
PSS解决了RSS的问题。它把共享库的内存按比例分摊到每个进程上。比如一个共享库占10MB,有5个进程在用,每个进程就分摊2MB。这样算出来的数字,才真正接近你的App「实际」占用的内存。
我个人习惯用PSS来做内存监控。为什么?因为它公平。你优化了PSS,系统整体内存压力就会下降。这是实打实的优化。
USS:最「干净」的指标
USS是进程独占的内存。它不包含任何共享部分。这个值适合用来分析「这个进程到底自己吃了多少」。但说实话,在实际优化中,USS的参考价值不如PSS大。因为共享库也是你App的一部分,你不能说「共享库的内存不关我事」对吧?
内存与性能的关系
内存和性能的关系,说白了就是一句话:内存不够,性能来凑。
为什么会这样?我举个例子。你的App需要加载一张图片。如果内存充足,图片可以常驻内存,下次打开秒开。但如果内存紧张,系统就会把图片回收掉,下次再加载就得重新解码——这就慢了。
更严重的是,当系统内存不足时,会触发LMK(Low Memory Killer)。它会直接杀掉你的进程。嗯,这就是你经常遇到的「闪退」或者「后台被杀」的根本原因。
我的经验:在Android上,PSS超过400MB就要警惕了。iOS上虽然机制不同,但原理类似。我曾经优化过一个项目,把PSS从500MB降到200MB,结果App的冷启动速度提升了30%。内存和性能,从来都是绑在一起的。
避坑指南
最后,分享几个我踩过的坑:
- 不要只看RSS:我曾经用RSS做内存监控,结果发现一个「内存泄漏」修了三天,最后发现是共享库版本更新导致的。浪费了时间。
- PSS才是王道:无论是Android的dumpsys meminfo,还是iOS的Xcode Memory Report,都建议优先看PSS。
- USS用于定位问题:当你发现PSS异常高时,可以用USS来排查是不是有独占内存泄漏了。
- 别忽略虚拟内存:虽然VSS很虚,但虚拟内存耗尽也会导致OOM。尤其是32位进程,虚拟地址空间只有4GB,很容易耗尽。
好了,这一章的内容就到这里。记住这四个指标,后面讲内存分析和优化的时候,你会用到的。
公众号:蓝海资料掘金营,微信deep3321