Publicação para fornecer como resolvemos isso - não elegante ou polido, e não uma resposta direta (não recebemos a real alocação de commit de um processo), mas identificamos o ofensor e encontramos um vazamento sutil de memória.
Peça desculpas por comentários, etc., mas essas foram ferramentas de uso rápidas. Com isso ...
Analisamos os resultados do comando pmap
e uma varredura de /etc/<pid>/smaps
data de processos, agregamos os mesmos para cópias do mesmo processo e os carregamos em uma planilha para análise. Nós tiramos fotos várias vezes ao dia durante uma semana e observamos a tendência no uso da memória. Isso nos mostrou, para um conjunto agregado de processos com o mesmo nome, as tendências de memória ao longo do tempo, o que nos permitiu identificar o conjunto de processos ofensivos.
O script de controle (executou um grupo de comandos e organizou os resultados em um arquivo)
gpmemstatFile=gpmemstat.$(date "+%F.%H.%M.%S.%N" | cut -c 1-23)
echo '-----------------------------------------------------' >> $gpmemstatFile
echo $(hostname) >> $gpmemstatFile
echo $(date) >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
echo >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
echo '/proc/meminfo' >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
cat /proc/meminfo >> $gpmemstatFile
echo >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
echo 'sar -r' >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
sar -r >> $gpmemstatFile
echo >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
echo 'sar -R' >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
sar -R >> $gpmemstatFile
echo >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
echo 'gpsmapstat (/proc/(pid)/smaps aggregates)' >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
gpsmapsstat httpd oninit fglrun java fastcgi gdcproxy >> $gpmemstatFile
echo >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
echo 'gppmapstat (pmap -d -x aggregates)' >> $gpmemstatFile
echo '-----------------------------------------------------' >> $gpmemstatFile
gppmapstat httpd oninit fglrun java fastcgi gdcproxy >> $gpmemstatFile
if [ -n "$1" ]; then
scp $gpmemstatFile $1
fi
O script para coletar dados do processo via pmap
para todos os processos de um nome específico (você pode usar outros mecanismos para identificar os processos a serem analisados). Isso resumiu o uso de memória agregada para todos os processos de um tipo.
printf "%8s %8s %8s %8s %8s %8s %8s %8s\n" name PID Total Resident Dirty Private Shared Unshared
for name in $@ ; do
unset sumTotalMemory sumResidentMemory sumDirtyMemory sumPrivateMemory sumSharedMemory sumUnsharedMemory
for pid in $( ps aux | grep $name | awk '{print $2}') ; do
xMemory=$(pmap -x $pid | tail -1)
totalMemory=$(echo $xMemory | awk '{print $3}')
if [ -n "$totalMemory" ] ; then sumTotalMemory=$(($sumTotalMemory + $totalMemory)) ; fi
residentMemory=$(echo $xMemory | awk '{print $4}')
if [ -n "$residentMemory" ] ; then sumResidentMemory=$(($sumResidentMemory + $residentMemory)) ; fi
dirtyMemory=$(echo $xMemory | awk '{print $5}')
if [ -n "$dirtyMemory" ] ; then sumDirtyMemory=$(($sumDirtyMemory + $dirtyMemory)) ; fi
dMemory=$(pmap -d $pid | tail -1)
privateMemory=$(echo $dMemory | awk '{print $4}')
if [ -n "$privateMemory" ] ; then
privateMemory=${privateMemory:0:${#privateMemory}-1}
sumPrivateMemory=$(($sumPrivateMemory + $privateMemory))
fi
sharedMemory=$(echo $dMemory | awk '{print $6}')
unset unsharedMemory
if [ -n "$sharedMemory" ] ; then
sharedMemory=${sharedMemory:0:${#sharedMemory}-1}
sumSharedMemory=$(($sumSharedMemory + $sharedMemory ))
unsharedMemory=$(($totalMemory - $sharedMemory))
sumUnsharedMemory=$(( $sumUnsharedMemory + $unsharedMemory ))
fi
#printf "%8s %8s %8s %8s %8s %8s %8s %8s\n" $name $pid $totalMemory $residentMemory $dirtyMemory $privateMemory $sharedMemory $unsharedMemory
done
if [ -n "$sumTotalMemory" ] ; then
printf "%8s %8s %8s %8s %8s %8s %8s %8s\n" $name Total $sumTotalMemory $sumResidentMemory $sumDirtyMemory $sumPrivateMemory $sumSharedMemory $sumUnsharedMemory
printf "%8s %8s %8s %8s %8s %8s %8s %8s\n" $name MiB $(($sumTotalMemory/1024)) $(($sumResidentMemory/1024)) $(($sumDirtyMemory/1024)) $(($sumPrivateMemory/1024)) $(($sumSharedMemory/1024)) $(($sumUnsharedMemory/1024))
printf "%8s %8s %8s %8s %8s %8s %8s %8s\n" $name GiB $(echo "scale=2; $sumTotalMemory/1024/1024" | bc) $(echo "scale=2; $sumResidentMemory/1024/1024" | bc) $(echo "scale=2; $sumDirtyMemory/1024/1024" | bc) $(echo "scale=2; $sumPrivateMemory/1024/1024"| bc) $(echo "scale=2; $sumSharedMemory/1024/1024"| bc) $(echo "scale=2; $sumUnsharedMemory/1024/1024"| bc)
fi
done
E o script para analisar todos os arquivos proc/<pid>/smaps
e agregar dados de memória para todos os processos de um nome específico (novamente, você poderia usar outros mecanismos para identificar os processos a serem analisados). E novamente isso resumiu o uso de memória agregada para todos os processos de um tipo.
printf "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n" name size rss pss shrdCln shrdDrty prvtCln prvtDrty refrncd swap
for name in $*; do
unset awkFiles
for pid in $( ps aux | grep $name | awk '{print $2}') ; do
if [ -e /proc/$pid/smaps ] ; then
awkFiles=${awkFiles}" /proc/$pid/smaps"
fi
done
if [ -n "$awkFiles" ] ; then
awk -v name="$name" '{
if ($1 == "Size:" ){
sizeSum+=$2
}
else if ($1 == "Rss:" ){
rssSum+=$2
}
else if ($1 == "Pss:" ){
pssSum+=$2
}
else if ($1 == "Shared_Clean:" ){
sharedCleanSum+=$2
}
else if ($1 == "Shared_Dirty:" ){
sharedDirtySum+=$2
}
else if ($1 == "Private_Clean:" ){
privateCleanSum+=$2
}
else if ($1 == "Private_Dirty:" ){
privateDirtySum+=$2
}
else if ($1 == "Referenced:" ){
referencedSum+=$2
}
else if ($1 == "Swap:" ){
swapSum+=$2
}
}
END { printf "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", name, sizeSum, rssSum, pssSum, sharedCleanSum, sharedDirtySum, privateCleanSum, privateDirtySum, referencedSum, swapSum}' $awkFiles
fi
done
Mais uma vez, não polido, e não a resposta real (ainda não sei como obter processos em uma lista classificada de carga de confirmação de memória), mas foi o truque aqui.