Memória Real do Kernel (RSS) & File Descriptors
Funções nativas do PHP como memory_get_usage() e memory_get_peak_usage() medem apenas a memória alocada dentro do heap da Zend Engine (o gerenciador interno para objetos, arrays e variáveis do PHP).
Elas são completamente cegas para:
- Extensões em C (
curl,imagick,gd,openssl,ext-sodium) - Alocações nativas via
malloc()/jemalloc/mimalloc - File Descriptors e sockets esquecidos abertos (
/proc/self/fd)
1. A Interface /proc/self/statm no Linux
No Linux, o kernel disponibiliza um arquivo virtual para cada processo: /proc/self/statm.
Ler esse arquivo não realiza I/O de disco físico; o kernel expõe a tabela de páginas de memória do processo em nanossegundos:
20480 12800 3840 256 0 10240 0Onde cada coluna representa:
- Tamanho Total do Programa (Size): Espaço total de memória virtual (em páginas).
- Resident Set Size (RSS): Memória RAM física real atualmente ocupada pelo processo (em páginas).
- Páginas Compartilhadas (Shared): Páginas mapeadas de bibliotecas compartilhadas.
- Texto / Código (Text): Segmento de código executável.
- Biblioteca (Lib): Páginas de bibliotecas dinâmicas.
- Dados + Stack (Data): Segmento de dados e pilha do processo.
- Páginas Modificadas (Dirty): Páginas físicas alteradas na RAM.
Como o Leakless Calcula o RSS Real
- Resolução de Página: Consulta o tamanho da página Linux via
posix_sysconf(POSIX_PC_SC_PAGESIZE)(normalmente4096bytes). - Parsing de Alta Performance:
ProcStatmParserlê/proc/self/statmnos limites da requisição. - Conversão para Megabytes: Converte a contagem de páginas diretamente para megabytes: $$\text{RSS (MB)} = \frac{\text{resident_pages} \times \text{page_size_bytes}}{1024 \times 1024}$$
2. Guardião de File Descriptors (/proc/self/fd)
Em workers persistentes, arquivos não fechados (fopen()), streams temporárias ou sockets de rede (fsockopen(), handles cURL) acumulam na tabela de processos do Linux.
Com o tempo, isso atinge o limite do sistema (ulimit -n), provocando o erro fatal: Too many open files
Como o FileDescriptorGuard Opera
Quando checkFileDescriptors: true (ou LEAKLESS_CHECK_FILE_DESCRIPTORS=true):
- Snapshot Inicial: Lê os symlinks de
/proc/self/fdnostartRequest(). - Auditoria de Pós-Requisição: Reinspeciona
/proc/self/fdnoendRequest(). - Identificação de Vazamentos: Detecta descritores abertos durante a requisição que não foram fechados.
- Logs Diagnósticos: Emite alertas detalhados com os caminhos dos arquivos e marca
$report->fileDescriptorsLeaked = true.