Other than Windows, unix manages an explicit parent-child relationships between processes. When a child process dies, the parent will receive a notification. It is then the duty of the parent process to explicitly take notice of the childs demise by using the wait() system call. The return value of the wait() is the process ID of the child, which gives the parent exact control about which of its children are still alive.
As long as the parent hasn't called wait(), the system needs to keep the dead child in the global process list, because that's the only place where the process ID is stored. The purpose of the "zombies" is really just for the system to remember the process ID, so that it can inform the parent process about it on request. If the parent "forgets" to collect on its children, then the zombie will stay undead forever. Well, almost forever. If the parent itself dies, then "init" (the system process with the ID 0) will take over fostership over its children and catch up on the neglected parental duties.