Como preencher 90% da memória livre?

167

Eu quero fazer alguns testes com poucos recursos e, para isso, preciso ter 90 % da memória livre cheia.

Como posso fazer isso em um sistema *nix ?

    
por Eduard Florinescu 08.11.2013 / 11:13

12 respostas

139
O

stress é um gerador de carga de trabalho que simula a tensão cpu / mem / io / hdd nos sistemas POSIX. Esta chamada deve fazer o truque no Linux < 3,14:

stress --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1

Para Linux > = 3.14, você pode usar MemAvailable para estimar a memória disponível para novos processos sem trocar:

stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1

Adapte a chamada /proc/meminfo com free(1) / vm_stat(1) / etc. se você precisar dele portátil.

    
por 08.11.2013 / 18:40
91

Você pode escrever um programa em C para malloc() da memória requerida e, em seguida, usar mlock() para impedir que a memória seja trocada.

Em seguida, deixe o programa aguardar pela entrada do teclado e desbloqueie a memória, liberte a memória e saia.

    
por 08.11.2013 / 13:36
44

Eu sugeriria executar uma VM com memória limitada e testar o software, pois seria um teste mais eficiente do que tentar preencher a memória na máquina host.

Esse método também tem a vantagem de que, se a situação de pouca memória causar erros em OOM em outro lugar e travar todo o sistema operacional, você apenas desligará a VM em teste em sua máquina e poderá executar outros processos úteis.

Além disso, se seu teste não for intensivo em CPU ou I / O, você poderá executar simultaneamente instâncias dos testes em uma família de VMs com uma variedade de tamanhos de memória insuficientes.

    
por 08.11.2013 / 16:25
29
  1. executar o linux;
  2. boot com o parâmetro de inicialização do kernel mem=nn[KMG]

(procure em linux / Documentation / kernel-parameters.txt para detalhes).

    
por 08.11.2013 / 13:40
28

Deste comentário da HN: link

Just fill /dev/shm via dd or similar.

swapoff -a
dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k
    
por 08.11.2013 / 13:00
18

Se você tiver ferramentas GNU básicas ( sh , grep , yes e head ), poderá fazer isso:

yes | tr \n x | head -c $BYTES | grep n
# Protip: use 'head -c $((1024*1024*2))' to calculate 2MB easily

Isso funciona porque o grep carrega toda a linha de dados na RAM (eu aprendi isso de uma forma bastante infeliz ao usar uma imagem de disco). A linha, gerada por yes , substituindo as novas linhas, será infinitamente longa, mas é limitada por head to $BYTES bytes, portanto o grep carregará $ BYTES na memória. O próprio grep usa 100-200KB para mim, você pode precisar subtrair isso para um valor mais preciso.

Se você também quiser adicionar uma restrição de tempo, isso pode ser feito facilmente em bash (não funcionará em sh ):

cat <(yes | tr \n x | head -c $BYTES) <(sleep $NumberOfSeconds) | grep n

A coisa <(command) parece ser pouco conhecida, mas geralmente é extremamente útil, mais informações aqui: link

Em seguida, para o uso de cat : cat esperará que as entradas sejam concluídas até a saída, e mantendo um dos tubos aberto, ele manterá o grep ativo.

Se você tiver pv e quiser aumentar lentamente o uso de RAM:

yes | tr \n x | head -c $BYTES | pv -L $BYTESPERSEC | grep n

Por exemplo:

yes | tr \n x | head -c $((1024*1024*1024)) | pv -L $((1024*1024)) | grep n

Usará até um gigabyte a uma taxa de 1 MB por segundo. Como um bônus adicional, pv mostrará a taxa atual de uso e o uso total até o momento. Claro que isso também pode ser feito com variantes anteriores:

yes | tr \n x | head -c $BYTES | pv | grep n

Apenas inserindo a parte | pv | mostrará o status atual (taxa de transferência e total, por padrão, eu acho - caso contrário, ver a página do usuário).

Por que outra resposta? A resposta aceita recomenda a instalação de um pacote (aposto que há uma versão para cada chipset sem precisar de um gerenciador de pacotes); a resposta mais votada recomenda a compilação de um programa em C (eu não tinha um compilador ou toolchain instalado para compilar sua plataforma de destino); o segundo top votou resposta recomenda executar o aplicativo em uma VM (sim deixe-me apenas dd sdcard interno do telefone sobre USB ou algo assim e criar uma imagem de caixa virtual); o terceiro sugere modificar algo na seqüência de inicialização que não preenche a RAM como desejado; o quarto só funciona na medida em que o ponto de montagem / dev / shm (1) existe e (2) é grande (remontar precisa de raiz); o quinto combina muitos dos acima sem código de exemplo; o sexto é uma ótima resposta, mas eu não vi essa resposta antes de criar minha própria abordagem, então eu pensei em adicionar a minha, também porque é mais curto para lembrar ou digitar se você não vê a linha do memblob é realmente o cerne da questão; o sétimo novamente não responde à pergunta (usa ulimit para limitar um processo); o oitavo tenta fazer você instalar o python; o nono acha que somos todos pouco criativos e, finalmente, o décimo escreveu seu próprio programa em C ++, que causa o mesmo problema que a resposta mais votada.

    
por 13.01.2016 / 00:43
15

Eu mantenho uma função para fazer algo similar em meus arquivos de ponto. link

function malloc() {
  if [[ $# -eq 0 || $1 -eq '-h' || $1 -lt 0 ]] ; then
    echo -e "usage: malloc N\n\nAllocate N mb, wait, then release it."
  else 
    N=$(free -m | grep Mem: | awk '{print int($2/10)}')
    if [[ $N -gt $1 ]] ;then 
      N=$1
    fi
    sh -c "MEMBLOB=\$(dd if=/dev/urandom bs=1MB count=$N) ; sleep 1"
  fi
}
    
por 08.11.2013 / 15:06
13

Qual a importância de uma solução simples em Python?

#!/usr/bin/env python

import sys
import time

if len(sys.argv) != 2:
    print "usage: fillmem <number-of-megabytes>"
    sys.exit()

count = int(sys.argv[1])

megabyte = (0,) * (1024 * 1024 / 8)

data = megabyte * count

while True:
    time.sleep(1)
    
por 08.11.2013 / 13:33
10

Que tal o ramfs, se existir? Montá-lo e copiar em um arquivo grande? Se não houver /dev/shm e nenhum ramfs - eu acho que um minúsculo programa em C que faz um grande malloc baseado em algum valor de entrada? Pode ter que executá-lo algumas vezes ao mesmo tempo em um sistema de 32 bits com muita memória.

    
por 08.11.2013 / 13:30
7

Se você quiser testar um processo específico com memória limitada, talvez seja melhor usar o ulimit para restringir quantidade de memória alocável.

    
por 08.11.2013 / 14:19
4

Eu acho que este é um caso de fazer a pergunta errada e sanidade ser afogada por pessoas que competem pela resposta mais criativa. Se você precisa apenas simular condições OOM, não precisa preencher a memória. Basta usar um alocador customizado e falhar após um determinado número de alocações. Essa abordagem parece funcionar bem o suficiente para o SQLite .

    
por 08.11.2013 / 23:01
2

Eu escrevi este pequeno programa C ++ para isso: link

A vantagem dessa implementação é que ela verifica periodicamente se precisa liberar ou realocar memória.

    
por 08.11.2013 / 14:27