Primeiro, sobre determinar o uso da memória. O VSS / VSIZE / VIRT não é o uso real da RAM pelo processo (como @psusi também observou). Existem algumas ferramentas que podem calcular o uso real, uma é uma ferramenta muito útil por Peter Willis do Yahoo !:
Duas notas importantes sobre sua configuração. Geralmente não é uma boa ideia usar:
MaxRequestsPerChild 0
A menos que você tenha escrito o aplicativo por conta própria. É bastante comum ter vazamentos de memória, portanto, após várias centenas (ou milhares) de solicitações, o uso de memória da criança aumentará e, eventualmente, excederá um nível razoável. Você provavelmente deve definir isso para ~ 200 e ver quanta memória eles usam após 200 solicitações. Isso tem que ser pesado com a quantidade de tempo que a desova do servidor demora. Se levar vários segundos e muitos recursos para forçar novos filhos, você deseja aumentar o valor (ou mesmo diminuí-lo se for leve).
Em segundo lugar, a menos que você esteja usando especificamente o prefixo de módulos não seguros, o preffork não é realmente preferido, já que usa mais memória:
The prefork MPM uses multiple child processes with one thread each. Each process handles one connection at a time. On many systems, prefork is comparable in speed to worker, but it uses more memory.
Por último, você provavelmente desejará passar e eliminar os módulos desnecessários. Tanto quanto eu sei, não há módulo personalizado para ajudar a fazer isso e você geralmente acaba tentando remover o maior número possível e verificar se o sistema ainda funciona. Isso é basicamente chute e checagem, mas vale a pena uma ou duas horas de tempo.