Bueno .. en ese caso tu archivo pasa por completo por PHP y este a su vez impone limitaciones en la memoria que puede gestionar en total para un script (su ejecución).
Podrías usar en lugar de readfile() .. passthru(). Esta función va enviando en bloques la información .. así que nunca cara a tu script PHP manejaría el total del tamaño del archivo que gestiona.
http://www.php.net/passthru
No sé que sistema operativo usas en el servidor .. pero en php.net hablan de su uso según el ejemplo que expones pero en lugar de tu readfile() usar:
Código PHP:
passthru("cat $id",$err);
Otras soluciones sería tal vez usando fopen() en bloques e ir entregando -de a poco- al cliente el archivo que lees igualmente en bloques. Lo importante es no forzar a PHP a que lea todo el archivo en "memoria" de una.
Un saludo,