Почему утечка памяти кажется неправильной для kernel_task, и почему OS X не может, поэтому сборщик мусора

11

Ранее мне говорили, что признаком того, что в некоторых приложениях есть утечка памяти, kernel_taskявляется большой объем памяти, обычно порядка гигабайт. Если неправильное kextиспользование этой памяти приводит к ошибкам, мы ожидаем увидеть расхождение между выделенной памятью и ожидаемой для нее, т.е.

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

вернет что-то, кроме слов «Wired» и «Name».

Во время написания моей диссертации я заметил, что изменение PDF, когда оно открыто в Preview, часто приводит к плохим вещам: иногда использование памяти kernel_taskможет возрасти примерно до восьми гигабайт или более. Если я убью предпросмотр, он мгновенно возвращается к нормальному состоянию . Так что, очевидно, что-то не так - и в этих условиях Preview теряет память.

Итак, мой вопрос заключается в следующем: если я знаю, что процесс утек оперативной памяти в результате внезапного и неожиданного увеличения площади kernel_task, почему OS X не может знать, что что-то пошло не так. Если убийственный Preview восстанавливает мою недостающую malloc()память, почему Дарвин не делает сборку мусора автоматически для меня?

У меня есть фундаментальное недоразумение, как работает управление памятью?

РЕДАКТИРОВАТЬ: (15/9/15)

Вот демонстрация того, о чем я говорю. Прежде всего, я kernel_taskотмечаю высокое использование памяти (обратите внимание, что предварительный просмотр открыт, он виден только в нижней части Activity Monitor, используя 333 МБ оперативной памяти):

Высокое использование памяти ядра

Следуя полезным замечаниям Эшли ниже, давайте выясним, сколько использует каждый 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
$

Так что, не огромное количество. Моя машина имеет как дискретные, так и встроенные графические процессоры; их водители используют только несколько МБ проводной памяти. По моему предположению, давайте убьем Preview и посмотрим, что происходит с объемом памяти kernel_task:

Предварительный просмотр убийства помогает

Предварительный просмотр завершен, и объем памяти ядра значительно сократился. До сих пор нет свидетельств изменения в использовании kext: выходные данные вышеупомянутой команды не изменяются.

Изменить : ошибка сообщается как № 22701036. Я все еще жду ответа от Apple. Нет ничего особенно интересного, если вы проверите процесс в ActivityMonitor, но, возможно, я что-то упустил.

Landak
источник
Я запутался в двух вещах - не могли бы вы уточнить? 1) Я думаю , что ваша diffкоманда сравнив Sizeи Wiredстолбцы из kextstatвывода. Я согласен с тем, что Sizeэто «выделенная память», но я не думаю, что Wired«ожидается выделение памяти» ( man kextstatописывает это как «Количество проводных байтов памяти ядра, которые занимает kext»). 2) Вы видите несоответствие между Sizeи Wiredкогда у вас есть проблема с Предварительным просмотром?
Эшли
1) Вы правы - я сравниваю элементы в Size и Wired from kextstat. Насколько я понимаю, если kext протекает, то выделенные байты и те, которые знает ядро , будут различаться. В данном случае я добавил это, чтобы показать, что у меня нет протекающего текста - так, 2) этого не происходит, когда Preview ест ram. Вместо этого kernel_taskсильно растет. Я постараюсь воссоздать эту проблему и сделать снимок :-).
Ландак
Благодарность! Подожди секунду: я просто пишу ответ, который может помочь.
Эшли

Ответы:

6

Ядро OS X не является сбор мусора; Libkern C ++ Runtime от IOKit требует от разработчиков управления собственной памятью.

Управление памятью Mac

Из Как работает управление памятью в Mac OS X?

Apple хорошо документирует самые низкие уровни ядра Маха и подсистемы виртуальной памяти в Интернете как часть документации для разработчиков.

Поскольку это ядро ​​было разработано Университетом Карнеги-Меллона , вы можете найти десятки статей, описывающих его довольно легко.

Другие источники

Вывоз мусора

Сборка мусора существует на уровне пользователя или приложения. Даже на этом уровне сборка мусора помогает, только если приложение сняло все претензии к памяти. Круговая зависимость может победить сбор мусора. Сборка мусора сама по себе является развивающейся областью исследований, и ее трудно понять .

Сообщить об ошибках и утечках памяти

Ошибки в OS X будут утечки памяти. Учитывая размер кодовой базы, это почти наверняка.

Пожалуйста, сообщайте о воспроизводимых ошибках непосредственно в Apple . Каждый отчет об ошибке помогает, и, возможно, именно ваш пример поможет инженерам Apple определить причину.

Грэм Милн
источник
Это разочаровывает, но, несомненно, правильно. Я сообщил об ошибке в Apple - я просто нахожу это раздражает!
Ландак
2
Пожалуйста, вы можете поделиться номером ошибки в качестве редактирования вашего вопроса. Другие, находящие ваш вопрос полезным, могут затем подать дубликаты ошибок, отмечая ваш оригинал. Куча связанных ошибок поможет оправдать больше времени на разработку.
Грэм Милн
4

Вот мое предположение, если предположить, что ваш Mac имеет встроенный графический процессор (например, Intel Iris Graphics).

Когда у вас открыт тезис в Preview, память графической карты используется для хранения изображения («текстуры») окна Preview, а также, возможно, некоторых неэкранных, но декодированных страниц из тезиса.

При наличии встроенной графической карты видеопамять фактически (частично?) Находится в системной памяти, которая распределяется между процессором и графическим процессором. На некоторых встроенных графических картах объем используемой системной оперативной памяти распределяется динамически (см. Apple HT204349 ).

Я предполагаю, что вы периодически видите ошибку в драйвере видеокарты и / или Preview, которая не высвобождает системную память правильно, когда Preview перезагружает ваш дипломный PDF. (Однако эта ошибка устраняется OS X / драйвер правильно освобождает память при выходе из Preview.)

Вы можете попробовать посмотреть на вывод kextstatи увидеть, Sizeувеличиваются ли числа в столбце при возникновении проблемы. Моя теория заключается в том, что увеличение памяти на 8 ГБ будет связано с драйвером графической карты.

Следующая команда (от комментариев по этому связанному и интересному ответу ) сортирует вывод , kextstatчтобы сделать его легче увидеть , какой Kext использует больше всего памяти (хотя это примечание сорт в Wiredколонке ... есть подобное, проще колдовство в этом ответьте с объяснением, если вы хотите настроить это).

kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n
Ashley
источник
Хорошая догадка - и огромное спасибо за полезный, отсортированный вывод kextstat. Тем не менее, это все еще не похоже на то, что происходит на самом деле: во время предварительного просмотра объем памяти com.apple.nvidia.driver.*не изменился. Я отредактировал свой вопрос, чтобы отразить это.
Ландак