Zombies are processes that have terminated, but have not been able to return their ending status to any parent. A zombie does not occupy any resources except a single process table entry. There is no code in memory, no data, no file descriptors, no pipes, no ports – nothing.

This happens because the parent (the spawning process) did not handle the child’s return properly – that is, it did not handle the SIGCHLD (or SIGCLD) signal properly. When such a parent finishes, then the process becomes a child of the init process (process ID #1). It is then expected that /bin/init will reap the process (cull the return status) using a wait() call.

However, sometimes init will not reap zombies, or the parents remain running and never reap. What’s worse, this handling of process children varies from operating system to operating system, so proper handling is often not portable. Handling spawned processes requires proper handling of the SIGCHLD signal, with the proper wait() commands.

One recommendation is thus: institute a SIGCHLD handler which will continue to wait for processes (using wait()) until there are no more processes. The (almost) pseudocode for such a handler would be:

handleCHLD {
while (deadProcessesExist)

It may be possible to kill off a zombie by sending a SIGCHLD to the parent process, but again this is not portable and only works on some System V derived systems. To do this, execute the command

kill -17 ppid

This sends a SIGCHLD signal to the parent process, given the proper process id (ppid) to send it to.

Further resources:

Zombies(5) from System V manpages
UNIX FAQ Question 3.13: How do I get rid of zombie processes that persevere?
Delve into UNIX Process Creation