我的 Mac 在几乎没有运行任何程序时似乎占用了大量内存。重启电脑后,只启动了一个终端和活动监视器。
htop
当只有两个进程在运行,并且根据“活动监视器”显示内存使用量接近 1GB 时,怎么会使用接近 5GB 的 RAM ?任何帮助或见解都将不胜感激。
htop
显示如下内容:
“活动监视器”显示以下内容:
答案1
这个解释起来还是挺容易的,我们来看一张刚才我的 Mac OS X 10.9.5 系统“活动监视器”的截图:
以此为参考,让我们根据屏幕截图右下角的项目做一些计算:
- 应用程序内存:1.59GB
- 文件缓存:1.32GB
- 有线记忆:1.30GB
将这些数字相加,总数为:4.21GB,与已用内存即4.21GB。
那么应用程序内存、文件缓存和有线内存之间有什么区别呢?所有这些都在 Apple 自己的支持文章中得到了非常明确的回答,标题为:“使用活动监视器读取系统内存并确定正在使用的 RAM 量”适用于 Mac OS X 10.8.5 及更早版本或本文“如何使用活动监视器”这是针对 Mac OS X 10.9 及更高版本的。以下是后面文章中的相关定义,因为根据您的屏幕截图,您使用的是 Mac OS X 10.9 或更高版本:
- 应用程序内存:应用程序及其进程当前使用的内存总量。
- 文件缓存:最近由应用程序使用且可供其他应用程序使用的内存。例如,如果您一直在使用 Mail,然后退出 Mail,则 Mail 使用的 RAM 将成为文件缓存的一部分,然后可供其他应用程序使用。如果您在其文件缓存内存被其他应用程序使用(覆盖)之前再次打开 Mail,则 Mail 的打开速度会更快,因为其文件缓存会转换回应用程序内存,而不是从启动驱动器加载其所有内容。
- 有线记忆:无法压缩或分页到启动驱动器的内存,因此必须保留在 RAM 中。进程使用的内存不能被其他进程借用。应用使用的有线内存量由应用的程序员决定。
现在看看这些定义,似乎“非活动”RAM 的最大用户实际上是文件缓存 RAM 区域。因为它是缓存,如果系统需要,它可以被立即覆盖/重新分配。但由于它确实是缓存,如果您重新启动以前使用该缓存内存的应用程序,该应用程序将启动得更快。
因此,了解了这一点,您可以放心地认为文件缓存使用的 1.32GB 内存实际上可以视为“空闲”内存,因为系统只会在可能的情况下获取并使用它。当然,它还有一个额外的好处,那就是如果之前的应用程序在文件缓存中保存了内容,那么在再次启动或使用它们时,可以加快它们的启动/使用速度。
另外,请注意“活动监视器”下方中央的运行图,名为“内存压力”。正如苹果所描述的那样:
内存压力图有助于说明内存资源的可用性。
这就是说,“内存压力”图表是 Apple 试图帮助直观地了解现代 Mac OS X 系统上内存管理的相对复杂性,因为 — — 正如你所见 — — 只盯着原始数字来解读内存使用情况有时会令人困惑。
答案2
请注意,内存“使用量”实际上很难估计。有一篇关于内存使用量的非常有启发性的帖子在 Stack Overflow 上的 Android 中;尽管 Mac OS X 和 Android 中使用的修改后的 Linux 内核之间存在明显差异,但仍有足够的相似之处,因此仍然具有相关性。
考虑到共享内存、每个进程的内存和虚拟内存,会导致对内存中的内容和不在的内容产生混淆。“活动监视器”并htop
使用不同的估计值。这并不令人担心,考虑到您安装了 8GB 内存,您使用的内存量(5GB)非常正常。
答案3
实际问题是,“几乎没有任何进程在运行”的说法是错误的。实际上有很多进程在运行。
虽然你可能会很快忽略其他进程,因为它们每个进程占用的内存很少,但有一个吨其中。
以下是每个进程的 RSS 饼图ps auxc
:
如您所见,所有微小的进程占据了总使用量的大部分。
根据您的定义,只有少数几个“实际正在运行”的小型应用程序(<200M)。其余的是单独的微小系统进程,总计达数 GB。
你可以自己检查它在你的系统上的样子:
import subprocess
import jc
import pygal
cmd_output = subprocess.check_output(['ps', 'auxc'], text=True)
data = jc.parse('ps', cmd_output)
pie_chart = pygal.Pie()
total_mem = 0
for item in data:
pie_chart.add(item['command'], item['rss'])
total_mem += item['rss']
pie_chart.title = f'Total: {str(round(total_mem / 1024, 2))} MB'
pie_chart.render_in_browser()
(对于 Nix 用户,需要、jc
和pygal
。)setuptools
lxml
nix-shell -p "python3.withPackages (p: with p; [ jc pygal setuptools lxml ])"