Tenho um programa consumindo muita memória durante as operações de E/S, o que é um efeito colateral da execução de muitas delas. Quando executo o programa usando direct_io, o problema de memória desaparece, mas o tempo que leva para o programa terminar o trabalho é quatro vezes maior.
Existe alguma maneira de reduzir o tamanho máximo do cache do buffer (buffer do kernel usado durante operações de E/S)? De preferência sem alterar as fontes do kernel.
Tentei reduzir /proc/sys/vm/
dirty_bytes etc. Mas isso não parece estar fazendo nenhuma diferença perceptível.
ATUALIZAÇÃO: usar echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys/vm/drop_caches echo 3 > /proc/sys/vm/drop_caches
Durante a execução do programa reduz temporariamente a quantidade de memória usada.
Posso de alguma forma limitar o pagecache, os dentries e os inodes em vez de liberá-los constantemente? Isso provavelmente resolveria meu problema.
Não percebi isso antes, mas o problema ocorre com todas as operações de E/S, não apenas com o particionamento. Parece que o Linux está armazenando em cache tudo que passa pela E/S até um certo ponto quando atinge quase o máximo de memória disponível, deixando 4 MB de memória livre. Portanto, há algum tipo de limite máximo para a quantidade de memória que pode ser armazenada em cache para E/S. Mas não consigo descobrir onde está. Ficando meio desesperado. Se eu não puder dividir por 2 em algum lugar nas fontes do kernel, farei isso com prazer.
Atualização de 12/12/2016: Desisti de consertar isso, mas algo me chamou a atenção e me lembrou desse problema. Tenho um disco rígido antigo com falha em casa e ele desperdiça recursos como um louco quando tento fazer algo com ele.
É possível que seja o caso de falha no HDD? O HDD em questão morreu um mês após a ocorrência do meu problema. Se for esse o caso, tenho minha resposta.
Responder1
Como você pergunta sobreprograma, você poderia usargrupos:
Crie um cgroup chamado group1 com um limite de memória (de 50GB, por exemplo, outros limites como CPU são suportados, no exemplo CPU também é mencionado):
cgcreate -g memory,cpu:group1
cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1
Então, se seu aplicativo já estiver em execução, traga-o para este cgroup:
cgclassify -g memory,cpu:group1 $(pidof your_app_name)
Ou execute seu aplicativo dentro deste cgroup:
cgexec -g memory,cpu:group1 your_app_name