为什么泄漏的内存似乎已分配给kernel_task,为什么OS X无法将其垃圾回收


11

以前我曾被告知,某些应用程序存在内存泄漏的迹象是kernel_task存在很大的内存占用,通常约为千兆字节。如果出了毛病kext导致此内存使用量,我们期望看到分配的内存与预期分配的内存之间存在差异,即

diff <(kextstat|tr -s ' ' | cut -d ' ' -f 5) <(kextstat| tr -s ' ' | cut -d ' ' -f 6) 

会返回“有线”和“名称”字样以外的内容。

在撰写论文时,我注意到在pdf在“预览”中打开时更改pdf常常会导致不好的事情发生:有时,的内存使用量kernel_task可能会增加到大约8 GB,甚至更多。如果我取消预览,它会立即恢复正常。因此,显然出了点问题–在这种情况下,Preview正在泄漏内存。

所以,我的问题是这样的:如果知道某个进程由于脚印的突然和意外增加而泄漏了ram kernel_task,为什么OS X不能知道出了什么问题。如果杀预览恢复我的思念malloc()“d内存,为什么达尔文为我做垃圾回收自动的?

我对内存管理的工作原理有基本的误解吗?

编辑:(15/9/15)

这是我在说什么的演示。首先,我注意到内存使用率很高kernel_task(注意:预览已打开,使用333 MiB的ram在活动监视器的底部可见):

高内核内存使用率

遵循下面Ashley的有用评论,让我们找出每个kext使用了多少:

$ kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n

...
...
...
   1249280 com.apple.driver.DspFuncLib
   1769472 com.apple.nvidia.driver.NVDAGK100Hal
   2629632 com.apple.nvidia.driver.NVDAResman
   6184960 com.apple.driver.AirPort.Brcm4360
$

因此,数量不多。我的机器同时具有离散GPU和集成GPU。他们的驱动程序仅使用少数MiB有线ram。凭我的直觉,让我们杀死Preview,看看下面的内存占用情况如何kernel_task

取消预览有帮助

预览不见了,内核的内存占用大大减少了。仍然没有证据表明kext用法发生了变化:上述命令的输出未更改。

编辑:错误报告为22701036。我仍在等待苹果的回应。如果您在ActivityMonitor中检查过程,没有什么特别有趣的,但是也许我遗漏了一些东西。


我对两件事感到困惑-您能否澄清?1)我认为您的diff命令正在比较输出中的SizeWiredkextstat。我同意这Size是“已分配的内存”,但我不认为它Wired是“预期要分配的”(man kextstat将其描述为“ kext占用的内核内存的有线字节数”)。2)您是否发现预览之间SizeWired何时出现差异?
阿什利2015年

1)您是对的-我正在比较Size和Wired from中的元素kextstat。我的理解是,如果KEXT泄漏,那么分配的字节和那些内核知道分配会有所不同。在这种情况下,我将其放在此处以表明我没有泄漏的kext-因此,2)当Preview食用ram时不会发生这种情况。相反,kernel_task增长很多。我将尝试重新创建此问题并拍照:-)。
Landak 2015年

谢谢!稍等:我正在写一个可能有用的答案。
阿什利2015年

Answers:


6

OS X核心不是垃圾收集。IOKit的libkern C ++运行时要求开发人员管理自己的内存。

Mac内存管理

摘自Mac OS X中的内存管理如何工作?

作为开发人员文档的一部分,Apple 在网上很好地记录了最低级别的Mach内核和虚拟内存子系统。

由于该内核是由卡内基梅隆大学开发的,因此您可以轻松找到许多描述它的论文

其他来源

垃圾收集

垃圾收集存在于用户或应用程序层。即使在这一层,垃圾回收也仅在应用程序已将所有声明释放到内存时才有帮助。循环依赖关系可能会破坏垃圾收集。垃圾收集本身是一个不断发展的研究领域,很难做到正确

报告错误和内存泄漏

OS X中的错误将导致内存泄漏。给定代码库的大小,这几乎可以肯定。

直接向Apple报告可复制的错误。每个错误报告都会有所帮助,也许您的示例将帮助Apple的工程师查明原因。


这令人失望,但无疑是正确的。我已将该错误报告给Apple了-我只是发现它很烦人!
Landak 2015年

2
请您分享错误编号,作为对问题的编辑。其他人发现您的问题很有帮助,然后可以提交重复的错误,指出您的原始错误。一堆相关的错误将有助于证明更多的工程时间。
格雷厄姆·米尔恩

4

假设您的Mac具有集成的GPU(例如Intel Iris Graphics),这是我的猜测。

当您在“预览”中打开论文时,图形卡内存将用于保存“预览”窗口的图像(“纹理”)以及论文中一些屏幕外但已解码的页面。

使用集成的图形卡,视频内存实际上(部分?)位于系统RAM中,该内存在CPU和GPU之间共享。在某些集成的图形卡上,使用的系统RAM量是动态分配的(请参阅Apple HT204349)。

我想您会间歇性地看到图形卡驱动程序和/或Preview中的错误,当Preview重新加载论文PDF时,该错误无法正确释放系统内存。(但是,OS X可以缓解此错误,当预览退出时,驱动程序可以正确释放内存。)

您可以尝试查看的输出,kextstat并在Size遇到问题时查看列中的数字是否增加。我的理论是,您提到的8GB增加将归因于显卡驱动程序。

下面的命令(从评论此相关的和有趣的答案)排序的输出kextstat,使之更容易看到哪些KEXT被使用最多的内存(虽然注意到这一排序Wired列...有一个类似的,简单的咒语在此回答与解释,如果你想调整这个)。

kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n

很好的猜测-非常感谢您提供了有用的,经过排序的输出kextstat。但是,实际情况并非如此:在预览预览期间,的内存占用量com.apple.nvidia.driver.*保持不变。我已经编辑了问题以反映这一点。
Landak 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.