内存基础概念:从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