Что такое зомби и что их вызывает? Существуют ли процессы зомби и объекты зомби?

Я могу найти вопросы о зомби, но ни один из них напрямую не касается того, что они есть, и почему и как они происходят. Есть пара, в которой рассматриваются процессы зомби в контексте ответа на конкретный вопрос, но не рассматриваются причины.

Есть также вопросы о зомби-процессах и вопросах о Objective-C/Cocoa связанных объектах зомби. Каковы различия или как они связаны? Является ли "EXEC_BAD_ACCESS" на Mac/iPhone (или подобная ошибка на других платформах) синонимом зомби?

Как можно предотвратить зомби и есть ли какие-либо рекомендации, которые помогут избежать их?

Было бы полезно иметь эту информацию в одном месте. Этот вопрос призван быть агностиком платформы/языка, если это возможно.

Ответ 1

Процессы зомби и объекты зомби совершенно не связаны. Процессы зомби - это когда родитель запускает дочерний процесс, а дочерний процесс завершается, но родительский элемент не выбирает код выхода ребенка. Объект процесса должен оставаться вокруг до тех пор, пока это не произойдет - он не потребляет ресурсов и мертв, но он все еще существует - следовательно, "зомби".

Объекты Zombie - это функция отладки Cocoa/CoreFoundation, которая помогает вам улавливать ошибки памяти - обычно, когда refcount объекта падает до нуля, он освобождается немедленно, но это затрудняет отладку. Вместо этого, если объекты зомби включены, память объекта не мгновенно освобождается, она просто помечена как зомби, и любые дальнейшие попытки ее использования будут регистрироваться, и вы можете отслеживать, где в коде, в котором использовался объект за всю его жизнь,

EXEC_BAD_ACCESS - это ваше исключение из-за мельницы "Вы использовали исключение плохого указателя", например, если:

(*(0x42)) = 5;

Ответ 2

Когда процесс заканчивается, большая часть его состояния все еще существует в ядре, потому что его родитель может все же захотеть взглянуть на несколько вещей, например на его возвращаемое значение, которое необходимо сохранить где-то. Когда родитель вызывает wait() или waitpid(), он сообщает ядру выбросить все это, потому что это сработало с ним. Пока это не произойдет, ребенок сохраняет pid и использует ресурсы. Эти невоспитанные дочерние процессы называются зомби. Даже убийство зомби не удалит его, оно должно быть получено (wait-ed-on) его родителем. Если родитель умирает, они передаются в "init" в unix-системах, единственной задачей которых является ожидание того, что вещи очистят их.

Я никогда не слышал о "объектах зомби", но я предполагаю, что это относится к вещам, которые либо не были очищены сборщиком мусора, либо имеют круговые ссылки или что-то подобное, так что они не собираются для очистки сборщика мусора. Метафора довольно похожа: fork() == malloc(), wait() == free() на определенном уровне. (Конечно, не идеальная метафора.)