Утечка памяти в наблюдателе fsevents в Mac OS X

Мне нужны уведомления файловой системы в Mac OS X, и я читаю из /dev/fsevents. Пример кода захвата fsevents в Mac OS X: http://www.codecollector.net/view/1066/raw_fsevents. В этом коде вы можете видеть, что буфер, считанный из /dev/fsevents, обрабатывается, как только он считывается. Но когда я это делаю, события отсутствуют из-за задержки, возникающей при обработке. Итак, я создал новый указатель char и memcpy прочел буфер из /dev/fsevents, добавил новый char* в очередь и обработал очередь в новом потоке. Но когда я обрабатываю char*, как в 'print_event' и 'dump_entry', указатель char* переустанавливается, и когда я проверяю strlen() после обработки, он говорит только длину 0 или 1 байт. Так что во время обработки происходит утечка памяти.

Любая идея, как удалить выделенный char *, это утечка памяти для большего количества событий. Пожалуйста, поделитесь своими мыслями по этому поводу. Заранее спасибо.


person Manikandaraj Srinivasan    schedule 13.02.2014    source источник


Ответы (1)


Просто любопытно: любая причина, по которой вы вручную обрабатываете /dev/fsevents, а не используете FSEvents, предназначенный для взаимодействия с ним (по крайней мере, для наиболее распространенных случаев)? /dev/fsevents довольно сложно общаться напрямую. Ars Technica сделала хороший обзор.

Для такого кода я бы отказался от malloc и memcpy. Это добавит много накладных расходов на управление вашей очередью. И я бы ушел от ручного управления потоками. Это именно та проблема, для решения которой предназначен GCD, в частности, с использованием dispatch_data. Он позволяет создавать неизменяемые блоки памяти, которые можно обрабатывать и манипулировать без необходимости копирования. Вы можете сделать так, чтобы dispatch_source читал /dev/fsevents и возвращал вам объекты dispatch_data. См. Чтение данных из дескриптора Руководства по программированию с параллелизмом.

Не совсем понятно, что вы подразумеваете под «указатель char * перестраивается». Вы имеете в виду, что вы изменяете одну и ту же переменную в двух потоках без блокировок?

Но если вам действительно не нужен необработанный доступ, я бы посмотрел на интерфейс FSEvents.

person Rob Napier    schedule 13.02.2014
comment
Спасибо за ответ. Раньше я читал, что интерфейс FSEvents ненадежен, он может пропускать события, и похоже, что я могу получать уведомления только на уровне каталога (мне нужно ставить в очередь каждый каталог). А что касается выравнивания char*, вы можете заметить некоторые изменения в char*, 'entry = (entry_t )(buf + len - остается); ' из кода. Поэтому, когда char обрабатывается полностью, когда я проверяю его на удаление, он говорит, что длина этого char* равна 0. Это означает, что указатель char* очищается во время вызовов функций dump_entry и print_event. Итак, как я могу остановить эту утечку ..? - person Manikandaraj Srinivasan; 14.02.2014
comment
Когда вы создаете новый указатель памяти с помощью malloc, отслеживайте его (не передавайте исходный указатель в print_event, передайте ему копию). Позже вы можете вызвать free для исходного указателя, чтобы освободить всю память. - person Rob Napier; 14.02.2014
comment
если я возьму еще одну копию, то мне придется освободить ее тоже правильно..? - person Manikandaraj Srinivasan; 15.02.2014
comment
Если вы снова скопируете его с помощью memcpy, да. Но pointer1 = pointer2 копирует указатель, а не память. Таким образом, вы должны освободить только один из этих указателей. - person Rob Napier; 17.02.2014