The old binary is no more surely released this way, though.  When the child is started, it's holding onto the old binary; if execve() is enough to persuade *it* to drop its reference to the old binary, when it switches to the new, then it's enough to make the original process do the same, so there was no gain in fork()ing; and if execve() isn't good enough to clear the un-fork()ed process's hold on the old binary, then it isn't good enough to do the same for the child, either.