Sua tarefa é criar um vazamento de memória . Este é um programa que usa muita memória, até o computador acabar e precisar fazer algumas trocas para evitar que ele acabe. A única maneira de liberar a memória é matando o programa no gerenciador de tarefas ou usando uma interrupção na linha de comando, como taskkill /im yourprogram /f
(no Windows), ou mesmo reiniciando o computador. Simplesmente fechar o aplicativo não deve impedir que ele continue consumindo memória.
Regras:
Bombas de garfo de qualquer tipo são proibidas. Isso significa que a famosa linha Bash
:(){ :|:&};:
é banida!O aplicativo deve ser apenas de thread único. Isso implica a regra da bomba de forquilha.
O programa não deve executar outros programas. Isso significa que você não pode simplesmente fazer algo assim
run(memoryfiller.exe)
. A única exceção a isso são os programas fornecidos com o sistema operacional ou o idioma, que não foram projetados principalmente para consumir memória (ou seja, eles têm outro objetivo). Isso significa que coisas comocat
eln -s
são permitidas.Você pode ocupar a quantidade de memória que desejar. Quanto mais melhor.
O código deve ser explicado completamente.
Boa sorte. Este é um concurso de popularidade, portanto o código com mais votos após 10 dias a partir da data de vencimento vence!
fonte
while(1)malloc(999);
?Respostas:
janelas
A API do Win32 permite alocar memória em outros processos e, em seguida, ler / gravar remotamente. Este programa possui apenas um encadeamento, usado para enumerar cada processo em execução no sistema e, em seguida, aloca repetidamente buffers de 1 MB em cada processo até que a alocação falhe. Quando termina com um processo, passa para o próximo. As alocações não são liberadas quando o programa de chamada termina - somente quando / se cada processo de destino terminar. Isso trava uma VM do Windows 7 de 2 GB em cerca de 10 segundos. Requer execução como administrador.
Compilar:
cl /MD leak.cpp /link psapi.lib
fonte
Java
Explicação
Você pode supor que, como não há referências no código (exceto as
count
que você pode ignorar com segurança), ele não pode vazar. No entanto, o finalizador cria duas novas Hydras e, embora não tenha referências para elas, elas permanecerão até a finalização. Isso significa que o programa apenas vaza memória durante a coleta de lixo - daí as chamadas paraSystem.gc()
eSystem.runFinalization()
.fonte
System.gc()
eSystem.runFinalization()
necessários? Ou seja, o gc é executado aleatoriamente às vezes, ou você precisa preencher alguma memória ou chamar gc?System.gc()
eSystem.runFinalization()
não seria necessário. A coleta de lixo aconteceria naturalmente devido à pressão da memória. No entanto, nesta aplicação, não há pressão de memória até a coleta de lixo começar a ser executada. Pensei em introduzir artificialmente alguns (por exemplo, movendo-menew Hydra()
dentro do loop), mas achei que isso era mais ruim.C
Utilizando a linguagem de programação C e testada com o kernel Linux 2.6.32-49-generic e libc-2.11.1.so.
Isso é conseguido através do bloqueio de quaisquer sinais, exceto SIGKILL e SIGSTOP.
Isso realmente me confundiu ... Matar ou fechá-lo resulta na finalização do processo, permitindo que o sistema operacional reivindique de volta qualquer memória que foi alocada pelo processo. Mas então eu pensei que, fechando-o, você pode querer fechar o terminal ou qualquer outro processo pai que execute o processo de vazamento de memória. Se eu entendi direito, resolvi esse problema bloqueando quaisquer sinais, que transformam o processo em um daemon quando o processo pai é encerrado. Dessa forma, você pode fechar o terminal em que o processo está sendo executado e ele continuará sendo executado e continuará a vazar memória.
O processo não bifurca.
Nenhum novo encadeamento é gerado.
Nenhum novo processo é gerado.
Tanto quanto o sistema operacional pode fornecer.
Comentários adicionados à fonte.
E finalmente, aqui está o código:
Para quem está interessado no que acontece se você mantiver este programa em execução: No meu sistema de teste com 2 GB de RAM e 4 GB de espaço de troca, foram necessários 10 minutos para preencher a RAM e trocar. O assassino da OOM iniciou seu trabalho e, três minutos depois, todos os processos foram mortos. Até mouse, teclado e tela foram descartados pelo sistema. /var/log/kern.log não mostra informações úteis, exceto os processos que foram eliminados.
fonte
Pure Bash
Não é uma bomba, garanto:
Parece muito com uma bomba de garfo e usa uma técnica recursiva semelhante, mas sem garfos. É claro que isso executará seu shell sem memória, portanto, é aconselhável iniciar um novo shell antes de colar este comando.
:
$@
(lista de argumentos) duplicada:
função é chamada com um argumento inicial:
Resultado:
Em uma edição anterior desta resposta, eu fiz
a=$(yes)
, mas notei a regra "O programa não deve executar outro programa", então, em vez disso, preciso usar purebash
sem chamar nenhum coreutils ou qualquer outra coisa.Aqui está mais um:
POR FAVOR, NÃO O EXECTE EM UMA MÁQUINA DE PRODUÇÃO
Novamente, isso não é uma bomba de forquilha - tudo é executado dentro de um segmento. Este parece facilmente trazer minha VM do Ubuntu de joelhos, com pouco espaço para recuperação, além da reinicialização.
Como na bomba de forquilha clássica, uma função recursiva
:()
é definida. No entanto, ele não realiza chamadas para si mesmo. Em vez disso, ele se chama com um argumento, que é chamado em uma substituição de processo . Como a substituição de processo funciona abrindo um descritor de arquivo/dev/fd/n
, isso não apenas consome memória de processo (bash), mas também consome alguma memória do kernel. Na minha máquina Ubuntu, isso tem o efeito de tornar o gerenciador de janelas inoperante após alguns segundos, e logo após terminar com esta tela:Clicar em
OK
seguida exibe esta tela:Nenhuma dessas opções parece ser de muita ajuda - nesse momento, reiniciar parece ser a única boa opção.
fonte
$ which yes
->/usr/bin/yes
XML
Em seguida, passe o documento para um analisador XML que não realiza a detecção de loop / recursão de referência de entidade. Por exemplo,
xpath
incluído no perl:Como funciona:
<boom a="&a;">
"&a;"
para"&b;&b;"
"&b;"
para"&c;&c;"
(no retorno, ele expande o outro"&b;"
)"&c;"
etc ...Se a expansão total pudesse ocorrer, haveria 2 ^ 52 de expansão "ka-boom!". Assumindo 2 bytes por caractere, ele tentará usar 64 PiB. A expansão vai "ka-boom!" de cada vez, para que você possa vê-lo consumir toda a memória no topo.
Isso ocorre por vários nomes, uma boa visão geral aqui: http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion
fonte
C ++
Este código foi inesperado! Ele desligou meu computador enquanto o gerenciador de tarefas estava aberto e mostrou que ele consumia 890 Mb de memória em 1 segundo e também travou. Se a resposta ajudou de alguma forma, por favor, marque como resposta, caso a sua dúvida
delete a;
não tenha sido solucionada, por favor, poste novamente. fornecido (devido anew int
) e depois recuperado (devido adelete a
) ao espaço livre no novo código abaixo.Então, concluo que NENHUMA RAM NESTE MUNDO PODE TRABALHAR ESTE CÓDIGO !!!
EDIT : Mas muitos processadores podem, por exemplo,
intel core 2 duo
não podem lidar com este código, masintel core i-series
podem (funcionou para mim ...)Lembre-se de que a resposta para a pergunta é o 1º código, o segundo é para explicação.
fonte
new int
usará o ponteiro, mesmo que você substitua o ponteiro, para que nunca possa acessá-lo novamente ... Portanto, nenhuma coleta de lixo é chamada e você preenche a memória mais rapidamente do que um garoto gordo come skittlesBrainFuck
Explicação:
Para entrar no loop, aumenta a célula para 1. Move-se para a próxima célula, aumentando para 1, desde que a última célula tenha sido positiva.
Geralmente, um intérprete do BrainFuck possui um limite rígido para o número de células na fita, mas alguns intérpretes adicionam células dinamicamente. Eles continuarão consumindo memória até que não haja mais consumo.
beef
é um desses intérpretes e está disponível no Ubuntu Software Center e minha execução atual em uma máquina não utilizada começou há 29 horas e consumiu 1 GB de RAM nesse período. Aqui está a saída detop
Ele tem 4 GB de cache e 6 GB de swap, então acho que vou atualizar esta resposta com a forma como ela foi realizada em cerca de 12 dias.
ATUALIZAÇÃO 03.24 17:11
ATUALIZAÇÃO 03.31 00:20
Então, está em funcionamento há 10 dias. Parece que estará rodando por pelo menos mais 10 antes que algo interessante aconteça.
fonte
C e POSIX
Aqui, estou buscando uma solução altamente portátil. O problema é que C puro não parece ter uma maneira de informar ao sistema operacional que a memória deve permanecer alocada após o encerramento do programa. Então, eu me permito usar o POSIX; a maioria dos sistemas operacionais tem alguma reivindicação de compatibilidade com POSIX, incluindo Windows, Linux e MacOS X. No entanto, só o testei no Ubuntu 12.04 32bit. Não requer permissões de superusuário.
Esta solução é essencialmente a
while(1){malloc(1);}
solução tradicional . No entanto, em vez de malloc, ele usa as funções de memória compartilhada POSIX. Como ele atribui um identificador de memória compartilhada a cada alocação, ainda é possível acessar a memória assim que o processo terminar. Portanto, o kernel não pode liberar a memória.fonte
C #
Esquecer de cancelar a inscrição de eventos antes que o manipulador fique fora do escopo fará com que o .NET perca memória até lançar OutOfMemoryException.
Explicação : Dentro do
while
loop, construímos um novo objeto, fazendo com que a estrutura aloque mais memória, mas também impedimos que a nova instânciaB
seja liberada quando ela sai do escopo, atribuindo um método de instância a um evento em uma classe diferente, o resultado é que a nova instânciaB
se torna inacessível a partir do nosso código, mas ainda existe uma referência, o que significa que o GC não a liberará até quea
também saia do escopo.Eventos estáticos têm a mesma armadilha, uma vez que nunca saem do escopo, eles são limpos apenas quando o processo termina, a menos que você cancele a inscrição do evento primeiro. Guarde sempre suas referências, pessoal!
O procedimento acima funciona com a mesma idéia: o manipulador se torna inacessível quando o
while
loop fica fora do escopo, impossibilitando o cancelamento da inscrição no evento, o que significa que a memória ficará lá até o término do programa. Eventos estáticos são sem dúvida mais perigosos que eventos de instância, porque você pode garantir que eles nunca saiam do escopo.EDIT : Você também pode fazer o mesmo com basicamente qualquer outro objeto, desde que você adicione uma referência e, ao mesmo tempo, garanta que não há como liberar essa referência.
Aqui está um exemplo que usa objetos e matrizes estáticos.
As matrizes continuam sendo adicionadas à lista, mas não há como limpar a lista sem modificar o código, o que seria impossível para aplicativos de código fechado. Aumentar o número passado para
Leak.Add
fará com que ele vaze mais rapidamente; se você o definir alto o suficiente, resultará no lançamento imediato de uma OverflowException.fonte
bash (sem utilitários externos)
Nenhuma bomba de garfo aqui.
Aviso: Pode matar o seu shell.
Apenas tentando criar uma matriz de números inteiros para referência, porque continuo esquecendo como os números inteiros se parecem.
Resulta em:
fonte
J (7)
AVISO: Isso congelou meu sistema quando o tentei (Windows 8, J 8.01, no terminal qt).
2#
dobra o comprimento do argumento duplicando cada elemento,^:_
encontra o ponto de correção da função fornecida (mas não existe um, ele faz um loop infinito),[_
chama isso_
como argumento.fonte
Haskell (número de Graham)
É muito simples: calcula o número de Graham
Ao contrário de outros exemplos aqui, ele não será executado para sempre ... ele usará muita CPU, mas teoricamente poderia ser encerrado. se não fosse pelo fato de armazenar o número ...
(de acordo com a wikipedia)
Portanto, a idéia é que a memória seja usada por uma (série de cada vez mais) enormes
Integer
(os Inteiros de Haskell são de tamanho arbitrário).Se você quiser testá-lo, pode ser necessário aumentar o tamanho da pilha ou carregá-lo dentro
ghci
.fonte
Inspirado por @comintern.
Substituindo / dev / null. Envolvendo o modo sorrateiro. Requer cabeçalhos de kernel, modo superusuário e um compilador funcional.
Diverta-se.
Makefile:
Código fonte:
Aviso: isso pode forçá-lo a reiniciar!
Para removê-lo:
fonte
Rubi
Todo mundo sabe que a soma (1 / n ^ 2) = pi ^ 2/6
Então, eu posso definir uma função de aproximação:
É claro que o (1..infinity) será executado livremente.
Observe, no entanto, que o uso de preguiçoso faria esse trabalho;)
fonte
C -
2825 caracteres (programa completo)Não execute esse, ou seu sistema ficará congelado rapidamente!
A chamada para o malloc reservará 9 bytes de memória e solicitará novas páginas de memória do sistema operacional regularmente. A memória alocada pelo malloc é vazada imediatamente, pois nenhum ponteiro para o endereço retornado é armazenado. Quando o sistema ficar sem memória (RAM e espaço de troca) ou atingir o limite de memória para o processo, o programa interromperá o ciclo while e será encerrado.
fonte
main(){while(malloc(9));}
salva outros 3 caracteres e preenche minha memória instantaneamente.VBScript
Estamos criando um dicionário que aponta para si mesmo. Então pensamos que destruímos o dicionário, definindo-o como Nothing. No entanto, o dicionário ainda existe na memória porque possui uma referência (circular) válida.
O loop, mas também o problema da memória, faz com que o programa seja interrompido. Após o desligamento do programa, a memória ainda está em uso. O sistema só pode ser restaurado reiniciando-o.
fonte
Sim e tmpfs
Por que escrever um novo programa quando se chega de graça com o Ubuntu?
Como você provavelmente sabe, ou já adivinhou, o Ubuntu monta / run / user / por padrão como um tmpfs, que é um tipo de disco RAM .
Você nem precisa fechá-lo. Ele se fechará educadamente, deixando um bom pedaço de memória alocado. Presumo que
yes
seja um programa de processo único e de thread único que não chame nenhum outro (gravar em um disco RAM existente também é trivialmente portátil para o idioma de sua escolha).Ele possui um bug menor: o Ubuntu limita o tmpfs / run / 1000 gravável pelo usuário a 1000 MB por padrão, portanto, o recurso de morte por troca pode não ser suportado na sua máquina imediatamente. No entanto, eu consegui corrigir isso na minha máquina com a seguinte solução rápida:
fonte
/run/user
diretório. Qual versão do Ubuntu você usa e o que instalou para isso?tmpfs
sistema de arquivos montado, é possível listá-lodf -t tmpfs
. Meu sistema Ubuntu tem um adorável grande/run/shm
disponível ...Bater
Aviso: O código a seguir tornará seu computador não inicializável.
Aviso: O código anterior tornará seu computador não inicializável.
Substitua / dev / sda pela sua unidade de inicialização. Isso grava o E8 FD FF no início do seu setor de inicialização. Ao inicializar, o BIOS lê seu setor de inicialização na memória e o executa. Esses opcodes são equivalentes a este assembly:
Isso é uma recursão infinita, que eventualmente causará um estouro de pilha.
fonte
jmp
vez decall
Haskell
Isso tenta somar os números contados. Haskell avalia as somas parciais, apenas se torna uma declaração de adição infinita. Se você executar o compilador com sinalizadores de otimização, ele pode não funcionar.
fonte
Bater
Desde que pode usar utilitários que não são especificamente projetados para consumir memória, eu me concentro em um utilitário para libertar memória:
swapon
. Isso é usado para permitir que o kernel libere memória gravando no disco.Este script executa duas otimizações: (1) Montar tmp como tmpfs (um tipo de disco RAM) para tornar o / tmp mais rápido e (2) criar um arquivo de troca para liberar memória. Cada um deles é razoável por si só, mas se um usuário descuidado faz as duas coisas, ele cria um ciclo de troca: quando o sistema operacional tenta trocar as páginas, ele grava nos tmpfs; isso faz com que os tmpfs usem mais memória; isso aumenta a pressão da memória, fazendo com que mais páginas sejam trocadas. Isso pode levar alguns minutos na minha VM, tempo suficiente para você assistir o sistema cavar um buraco usando
top
.Fechar o programa faz pouca diferença, já que o próprio programa aloca quase nenhuma memória. Na verdade, não é trivial liberar memória, pois você não pode liberar memória desmontando os tmpfs antes de você
swapoff
o arquivo de troca, e isso é difícil de fazer até que você libere memória.Essa resposta pode ser considerada uma advertência contra cegar aplicando truques legais da rede sem entendê-los.
fonte
Perl
Usa referências circulares. A contagem de referência para as variáveis nunca chegará a 0 e as referências nunca serão coletadas como lixo.
Você pode precisar ser paciente, mas é garantido que você engasga seu sistema. O disco começaria a girar mais rápido e os vapores poderiam estar visíveis.
fonte
PHP (somente linux):
Este código não foi testado, já que não tenho um computador linux com o php em execução.
Mas esta é a minha prova de conceito:
Isso preencherá a memória com enormes imagens RGBA (10000x10000 pixels).
A única maneira de desligar esse bebê é desligar a energia.
O código está todo comentado.
Qualquer melhoria, dúvida, bug ou qualquer coisa, use a caixa de comentários abaixo.
fonte
Python - 56
Cria uma classe, define um método para definir atributos, define um atributo e cria uma instância inicial da qual ele tenta definir um atributo.
Uma função recursiva simples (
def f(x):f(x)
) parecia um pouco sem imaginação, então decidi nunca realmente chamar uma função.O gerenciamento de memória pode capturar a profundidade da recursão, mas realmente depende da implementação.
Se esta é uma bomba de garfo, por favor me diga.
fonte
RuntimeError: maximum recursion depth exceeded while calling a Python object
. Mesmo a configuração do limite máximo de recursãosys.setrecursionlimit
quase sem memória é usada antes de travar com uma falha de segmentação.Perl
É simples, mas senti vontade de jogar golfe.
Após duas iterações,
$x
contém uma referência à matriz que contém uma referência à matriz que contémundef
.O uso da memória é linear no tempo, com pequenas alocações, mas levou apenas alguns segundos para desacelerar gravemente meu gerenciador de janelas no meu sistema Linux Ubuntu. Meio minuto depois, o assassino da OOM cuidou disso.
fonte
ECMAScript 6:
Ungolfed:
Nota: Ele usa
setTimeout
, que é definido como parte do Timers - o HTML Living Standard .Experimente no Mozilla Firefox (você pode colá-lo no console do desenvolvedor). O Firefox continua consumindo mais e mais memória e os usos
100%
da CPU em uma máquina de núcleo único (em uma máquina de quatro núcleos, como a minha, ela usa25%
a CPU). Ele também tem o benefício adicional de que você não pode impedi-lo; se você pode abrir o gerenciador de tarefas, pode matar o Firefox com ele.fonte
Bater
Criar um arquivo vazio
test
Substitua
/dev/null/
por este arquivo de texto$ sudo mv test /dev/null
Isso funciona de maneira semelhante à resposta do @ Comintern. Toda a saída para
/dev/null
agora será anexada a esse arquivo de texto, que com o tempo se tornará enorme e trava o sistema.fonte
/dev
existe umdevtmpfs
, ele pode ser preenchido e prejudicar o sistema. Suponho que essa seja a intenção desta resposta.Bash: 7 caracteres
Essa deve ser a solução mais simples do bash. Sem garfos, sem trapaça.
É aconselhável não executar isso como root.
fonte
unset
a variável, a memória permanecerá alocada até que o shell seja morto. Você pode assistir a carnificinatop
.unset x
a memória. O pdksh também libera a memória, mas o ksh93 falha em liberá-lo eexit
no ksh93 despeja o núcleo.yes
seja interrompida, e nesse ponto ele permanece lá,unset
sem efeito. Mas isso está em um sistema de memória grande e ter uma variável de vários gigabytes não parece incomodá-lo (até que finalmente decida matar o shell).C
Bem, é preciso memória página após página e, finalmente, não resta memória.
fonte
Rubi
Ele acrescenta infinitamente (auto-referências recursivas) referências a si próprio.
Descobri essa pequena joia quando alguém quebrou minha caixa de areia Ruby com ela . : D
Demonstração dos aspectos recursivos:
fonte
C ++ 79
Não-golfe
Corrigi minha entrada para incluir a chamada do principal.
fonte