Escreva um programa que seja executado para sempre e aloque mais e mais memória no heap quanto mais tempo ele for executado, pelo menos até atingir o limite do sistema operacional na quantidade de memória que pode ser alocada.
Muitos kernels, na verdade, não reservam a memória que você aloca até que você a use para alguma coisa; portanto, se o seu programa estiver em C ou em algum outro idioma de baixo nível, você precisará escrever algo em cada página. Se você estiver usando uma linguagem interpretada, provavelmente não precisará se preocupar com isso.
O menor código vence.
(reduce conj [] (range))
(Clojure) chega a 737mb e depois para de crescer. Idk como não está subindo continuamente. Ele "pensa" que quero imprimir a lista inteira no final, para que não jogue nada fora. Muito frustrante.Respostas:
Funge-98 (
cfunge
), 1 byteEu teria postado isso antes, mas decidi testá-lo e demorou um pouco para que meu computador voltasse a um estado utilizável.
cfunge
armazena a pilha do Funge na pilha do sistema operacional (que é facilmente verificável executando o programa com um pequeno limite de memória, algo que eu deveria ter feito antes!), portanto, uma pilha que cresce infinitamente (como neste programa, que apenas empurra9
repetidamente; Os programas Funge agrupados desde o final de uma linha até o início, por padrão) alocam a memória para sempre. Esse programa provavelmente também funciona em algumas implementações do Befunge-93.Mais interessante:
Essa foi minha primeira ideia e é uma alocação infinita que não depende da pilha Funge (embora ela também exploda a pilha Funge). Para começar, o
"
comando envia uma cópia do restante do programa para a pilha (é uma string e o programa se enrola, de modo que a cotação próxima também serve como cotação aberta). Em seguida, oN
reflete (não tem significado por padrão), fazendo com que o programa seja executado para trás. Ele"
é executado novamente e empurra o programa para a pilha - ao contrário, desta vez, com aN
parte superior da pilha -, em seguida, o programa gira, carregando uma biblioteca com um nome de quatro letras (4(
; aNULL
biblioteca faz parte decfunge
biblioteca padrão).NULL
define todas as letras maiúsculas para refletir, de modo queL
reflete, o#
pula a carga da biblioteca no caminho de volta,4
empurra o lixo que não nos interessa para a pilha e todo o programa se repete desde o início. Dado que o carregamento de uma biblioteca várias vezes tem efeito e requer que a lista de comandos da biblioteca seja armazenada uma vez para cada cópia da biblioteca (isso é implícito na semântica do Funge-98), ele vaza memória através do armazenamento sem pilha (que é um método alternativo de definição de "heap", relativo ao idioma e não ao SO).fonte
0
; é possível que a implementação do Funge ou o sistema operacional encontre uma maneira de otimizar isso, considerando que a memória em questão já está cheia de zeros). Eu apenas peguei9
arbitrariamente.Brainfuck, 5 bytes
Isso requer um intérprete que não tenha limite no comprimento da fita.
fonte
Bash + coreutils, 5
ou
Ruby, 5
yes
produz uma saída sem fim. Colocaryes
backticks diz ao shell para capturar toda a saída e depois executar essa saída como um comando. O Bash continuará alocando memória para essa sequência interminável até que o heap se esgote. É claro que a saída resultante acabaria sendo um comando inválido, mas devemos ficar sem memória antes que isso aconteça.Obrigado a @GB por apontar que também é um poliglota em rubi.
fonte
Python, 16 bytes
Mantém o aninhamento
a
até que seja atingido um erro:As primeiras iterações (como tuplas) são assim:
e assim por diante.
fonte
> <> (Peixe), 1 byte
Experimente aqui!
0
pode realmente ser substituído por qualquer número hexadecimal 1-f.Explicação
0
in> <> simplesmente cria um codebox 1x1 para o peixe nadar. Ele constantemente adiciona um0
na pilha, nada direito, o que volta ao redor0
, adicionando-o novamente à pilha. Isso continuará para sempre.fonte
.
(ou qualquer caractere que não seja um espaço em branco) para mover0
a linha de execução.0000000...
como um único inteiro literal, e a string que ele constrói é o que continua consumindo mais memória. Um programa que funcione da maneira que funciona seriaa
(empurra 10 infinitamente).Java 101 bytes
Captura do programa principal em um loop sem fim após criar e jogar fora um objeto. A coleta de lixo faz o trabalho de vazar criando 2 objetos para cada um excluído
fonte
Perl, 12 bytes
Em perl, o
x
operador, com uma sequência à esquerda e um número à direita, produz uma sequência repetida. Então"abc" x 3
avalia como"abcabcabc"
.O
x=
operador modifica o argumento esquerdo, substituindo o conteúdo da variável à esquerda pelo resultado de repetir o conteúdo tantas vezes quanto o lado direito indicar.O Perl possui várias variáveis incorporadas de nome estranho, uma das quais é
$"
, cujo valor inicial é um espaço único.O
redo
operador pula para o início do gabinete{}
.A primeira vez que o
x=
operador é feito, ele muda o valor de$"
partir" "
"para" "
, que é de 9 espaços.Na segunda vez em que o
x=
operador é concluído, ele altera o valor de$"
para" "
, que é 81 espaços.Na terceira vez,
$"
torna-se uma série de espaços de 729 bytes.Acho que você pode ver onde isso está indo :).
fonte
$_.=7
no meu loop, mas percebi que, se eu pudesse usá-x=
lo, a memória ficaria muito mais rápida e, em seguida, corriperldoc perlvar
para escolher algo adequado.{$^O++;redo}
é um byte mais curto quando^O
é um únicochr(15)
byte. Embora desperdice memória a uma taxa MUITO mais lenta - são necessárias 1000000000 iterações no Windows para desperdiçar um byte. Funcionará em qualquer sistema operacional cujo nome comece em letra latina.sed, 5 bytes
Golfe
Uso (qualquer entrada serve)
Explicado
Captura de tela
Experimente Online!
fonte
Haskell,
2319 bytesImprimir a soma de uma lista infinita
fonte
sum
é definido comofoldl (+) 0
, e o que deve parar a análise de rigidez para impedir a explosão de thunk? Você o executou compilado com otimizações?sum
não saberá antecipadamente que a lista é infinita e,print
na soma, deve ser avaliada primeiro. E sim, eu o compilei com otimizaçõesInteger
, os números são ilimitados e a memória obtida pelo resultado atual do bignum realmente aumentaria.sum xs = foldl (+) 0 xs
pode ser executado em pilha constante, como qualquer loop imperativo .foldl' (+) 0 xs
certamente vai. Portanto, a única coisa que aloca memória com certeza é o resultado intermediário do bignum.C ++ (usando o compilador g ++),
272315 bytesAgradeço ao Neop por me ajudar a remover 4 bytes
Essa solução realmente não vaza nenhuma memória porque aloca tudo na pilha e, portanto, causa um estouro de pilha. É simplesmente infinitamente recursivo. Cada recursão faz com que alguma memória seja alocada até a pilha estourar.
Solução alternativa
Esta solução realmente vaza memória.
Saída Valgrind
Esta é a saída do Valgrind após o término do programa por vários segundos no tempo de execução. Você pode ver que certamente está vazando memória.
fonte
int
até que eu vi o seu, então obrigado!C++
, apenas o dialeto do g ++: o C ++ proíbe chamar main; C ++ requerint main...
declaração. Mas a solução ainda é puro :-)main
.JAVA,
817978 bytesJAVA (HotSpot)
7170 bytesMais curtas do que as outras respostas Java no momento em que publiquei (81, depois 79 bytes):
Conforme sugerido por @Olivier Grégoire, um outro byte pode ser salvo:
A colocação
x+=x.intern()
como o incremento do loop for não ajudaria em nada, porque ainda é necessário um ponto-e-vírgula para finalizar a instrução for.Conforme sugerido por @ETHproductions, apenas o uso de
x+=x
obras também:O que também pode se beneficiar da dica de @Olivier Grégoire:
Minhas únicas dúvidas sobre isso é que não é garantido alocar dados no heap , pois uma JVM eficiente pode facilmente perceber que
x
nunca escapa à função local. O usointern()
evita essa preocupação, porque as seqüências internas acabam sendo armazenadas em um campo estático. No entanto, o HotSpot gera umOutOfMemoryError
código para esse código, então acho que está tudo bem.Atualização: @Olivier Gregoire também apontou que o
x+=x
código pode ser executado emStringIndexOutOfBoundsException
vez deOOM
quando há muita memória disponível. Isso ocorre porque o Java usa oint
tipo de 32 bits para indexar matrizes (e Strings são apenas matrizes dechar
). Isso não afeta ax+=x.intern()
solução, pois a memória necessária para o último é quadrática no comprimento da string e, portanto, deve ser dimensionada na ordem de 2 ^ 62 bytes alocados.fonte
x+=x;
?x+=x.intern()
atrás do último ponto e vírgula do loop forintern
mas fiquei muito feliz com Inseguro e finalizei que parei de olhar, haha. Originalmente, essa pergunta especificava "vazamento de memória", e é por isso que não fiz apenas uma resposta concat em string.# Java (HotSpot), 71 bytes
). Dessa forma, você não precisa se preocupar com a solução potencialmente enganadora; programas específicos de implementação são comuns não apenas no golfe, mas também no mundo mais amplo da programação, e desde que você esteja ciente do que está fazendo às vezes pode ser mais apropriado do que um programa portátil para, por exemplo, fora do script.x+=x;
não esgota toda a memória. Com 64 GB, recebo umStringIndexOutOfBoundsException
, não um OOM. Com.intern()
eu ainda recebo o OOM.Perl 6 , 13 bytes
Explicação:
@ =
armazena o resultado em uma matriz sem nomeeager
faça a seguinte lista ansiosa0 .. *
faixa infinita começando em zerofonte
///, 7 bytes
Substitua constantemente
a
poraa
ad nauseum.fonte
aad naauseum
ad nauseam
=>aad naauseaam
//a/
? Isso parece substituir para sempre `` (nada) pora
, mas não tenho certeza se isso está exatamente especificado.Python 3, 16 bytes
Isso vem do fato de que não há limite para o tamanho inteiro no Python 3; em vez disso, os números inteiros podem ocupar a quantidade de memória que o sistema pode suportar (se algo sobre minha compreensão disso estiver errado, me corrija).
fonte
Ferrugem, 46 bytes
Percebe algo interessante sobre esse programa Rust, vazando alocações de heap até ficar sem memória?
É isso mesmo, nenhum bloqueio inseguro. O Rust garante a segurança da memória em código seguro (sem leitura de dados não inicializados, leitura após liberação, liberação dupla etc.), mas os vazamentos de memória são considerados perfeitamente seguros. Existe até uma função explícita para fazer o compilador esquecer a limpeza RAII de variáveis fora do escopo, que eu uso aqui.
fonte
Conjunto hexagonal TI-83, 7 bytes
Cria appvars indefinidamente até que um
ERR:MEMORY
seja lançado pelo sistema operacional. Corra comAsm(prgmM)
. Eu conto cada par de dígitos hexadecimais como um byte.fonte
Python, 8 bytes
O OP permitiu a tecnicidade de um programa que tecnicamente não é executado "para sempre", mas aloca mais memória do que qualquer computador poderia suportar. Este não é um googolplex (ou seja
10**10**100
, 11 bytes), mas ingenuamente, a base de log 2 do número éou seja, 10 ^ 94 bits para representá-lo. WolframAlpha coloca isso como 10 ^ 76 maior que a deep web (lembre-se de que existem 10 ^ 80 átomos no universo ).
Por que 2 em vez de 9 você pergunta? Não faz muita diferença (usar 9 aumentaria apenas o número de bits por um fator de
log2(9) = 3.2
, o que nem altera o expoente). Mas, por outro lado, o programa roda muito mais rápido com 2, pois o cálculo é mais simples. Isso significa que ele preenche a memória imediatamente, ao contrário da versão 9, que demora um pouco mais devido aos cálculos necessários. Não é necessário, mas é bom se você quiser "testar" isso (o que eu fiz).fonte
Geléia ,
32 bytes-1 byte graças a Dennis (
W
envoltórios)Um link (ou seja, função ou método), que também funciona como um programa completo, que recursivamente agrupa sua entrada em uma lista.
A entrada começa como zero, então a primeira passagem cria a lista.
[0]
A segunda passagem faz isso.
[[0]]
A terceira passagem faz isso
[[[0]]]
e assim por diante ...
3 byter anterior, que vaza muito mais rápido:
concatena recursivamente todas as sublistas contíguas não vazias de sua entrada para sua entrada.
[0]
->[0,[0]]
->[0,[0],[0],[[0]],[0,[0]]]
e assim por diante ...fonte
‘ß
deve ser suficiente.Wß
ainda deve caber a conta embora.Java 7, 106 bytes
Menos Golfe
O
finalize
método é chamado em um objeto pelo coletor de lixo quando a coleta de lixo determina que não há mais referências ao objeto. Eu simplesmente redefinii esse método para fazer um loop para sempre, para que o coletor de lixo nunca libere a memória. Nomain
loop, crio novos objetos que nunca serão limpos e, eventualmente, isso consumirá toda a memória disponível.Java 7 (alternativa divertida), 216 bytes
Menos Golfe
Este é mais divertido do que qualquer outra coisa. Esta resposta faz uso da
Unsafe
biblioteca Sun, que é uma API interna não documentada. Pode ser necessário alterar as configurações do compilador para permitir APIs restritas.Unsafe.allocateMemory
aloca uma quantidade especificada de bytes (sem nenhuma verificação de limite) que não está no heap e não está sob o gerenciamento de coletor de lixo do java, portanto, essa memória permanecerá até você chamarUnsafe.freeMemory
ou até que a jvm fique sem memória.fonte
Haskell, 24 bytes
O principal problema em Haskell é vencer a preguiça.
main
precisa ter algumIO
tipo, então simplesmente chamarmain=f 9
não funcionaria. Usarmain=pure(f 9)
eleva o tipo def 9
para umIO
tipo. No entanto, o uso de construções comomain=pure 9
não faz nada,9
é retornado ou exibido em lugar nenhum, mas simplesmente descartado; portanto, não há necessidade de avaliar o argumento depure
, portantomain=pure(f 9)
, não faz com que nenhuma memória seja alocada comof
não é chamada. Para impor a avaliação, o$!
operador existe. Simplesmente aplica uma função a um argumento, mas avalia o argumento primeiro. Portanto, usarmain=pure$!f 9
avaliaf
e, portanto, aloca continuamente mais memória.fonte
f x=f x
obras também, certo? (−2 bytes)f x=f x
produz um loop infinito, mas sem alocar nova memória.f!x=x*f(x*x)
deve torná-lo à prova de otimizações.dc, 7 bytes
[ddx]
envia uma string contendo "ddx" para a pilha.dx
duplica e depois executa como código (deixando uma cópia na pilha). Quando executado, ele faz duas duplicatas e depois executa uma, deixando mais uma cópia na pilha de cada vez.fonte
Haskell (usando o ghc 8.0.1), 11 bytes
Recursão não-cauda.
main
chama a si mesmo e depois a si próprio novamente.fonte
Stack space overflow: current size 33624 bytes.
33k parece muito baixo em contraste com os 6G de memória total que o sistema operacional está relatando.C (linux), 23 bytes
sbrk()
incrementa a parte superior do segmento de dados pelo número especificado de bytes, aumentando efetivamente a quantidade de memória alocada para o programa - pelo menos conforme relatado noVIRT
campo detop
saída. Isso funciona apenas no Linux - a implementação do macOS é aparentemente uma emulação que só permite alocação de até 4 MB.Portanto, uma resposta um pouco mais geral:
C, 25 bytes
Eu assisti no macOS Activity Monitor. Foi até cerca de 48 GB e, eventualmente, o processo recebeu um sinal SIGKILL. FWIW meu macbook pro tem 16GB. A maior parte da memória usada foi relatada como compactada.
Observe que a pergunta exige efetivamente que cada alocação seja gravada, o que não acontece explicitamente aqui. No entanto, é importante observar que, para cada
malloc(9)
chamada, não são apenas os 9 bytes solicitados pelo usuário que estão alocados. Para cada bloco alocado, haverá um cabeçalho de malloc que também é alocado de algum lugar no heap, o qual é necessariamente gravado pelosmalloc()
internos.fonte
malloc()
bloco ed ainda deve ter seu próprio espaço alocado real. Isso funciona no macOS e no Ubuntu.main(){main(malloc(9));}
, mas, para não empilhar o estouro, ele precisa de otimização de chamada de cauda, e o gcc não parece querer fazer isso nomain
...Perl, 4 bytes
Executa-se, no intérprete atual. Quando concluída, a execução retorna ao script de chamada, que requer uma pilha de chamadas.
fonte
Raquete, 13 bytes
Não tenho certeza se minha resposta se enquadra nessa pergunta. Informe-me se devo remover esta resposta.
fonte
l
como uma função que faz recursão sem chamada de cauda. eu diria que conta.JavaScript
2221171615 bytesEconomizou 4 bytes envolvendo a lista em outra lista, como na resposta Jelly de @Jonathan Allan.
Guardado 1 byte graças a @ETHProductions
Solução alternativa 15 bytes (funciona apenas com chamadas de cauda adequadas)
fonte
f=_=>f();f()
? 12 bytesa=0
. A primeira iteração resultaria ema=[undefined]
Ruby, 11 bytes
Mantém empurrando
9
para$*
, que é uma matriz inicialmente segurando os argumentos de linha de comando para o processo de rubi.fonte
05AB1E , 2 bytes
Experimente online! Apenas continuará empurrando
abcdefghijklmnopqrstuvwyxz
para a pilha por toda a eternidade.Todas as soluções possíveis de 2 bytes:
fonte
Python, 35 bytes
a
nunca é liberado e fica maior até você atingir umMemoryError
Você pode ver a execução no Python Tutor .
fonte
a+=a,
?TI-BASIC, 8
(todos os tokens de 1 byte e duas novas linhas)
Isso vaza memória continuamente porque o fluxo de controle estruturado, como o
While
fechamento antecipado por umEnd
e empurra algo na pilha (não a pilha do SO, uma pilha separada na memória de pilha) para acompanhar isso. Mas aqui estamos usandoGoto
para deixar o loop (para que nãoEnd
seja executado para remover a coisa da pilha), elaWhile
é vista novamente, a coisa é empurrada novamente, etc. Portanto, ela continua pressionando-a até vocêERR:MEMORY
fonte