Programa mais curto que aloca memória continuamente


49

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.


13
Um estouro de pilha é uma solução válida? A memória precisa vazar ou apenas ser alocada?
Wheat Wizard

11
@WheatWizard A memória não precisa ser vazada, mas deve ser alocada mais rapidamente do que é desalocada.
precisa saber é

2
A única vez que quero que meu programa consuma memória infinita, não consigo. (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.
Carcigenicate

14
Nota para si mesmo: salve o código antes do teste. Apresentando MEM-vazamentos pode falhar IDE ...
steenbergh

11
Eu acho que você deve adicionar outro desafio de golfe, semelhante, mas separado disso, exigindo que o programa consuma memória mais rapidamente do que uma função linear do tempo. Para o desafio atual , fazer um loop para sempre e alocar um único byte deve ser bom. Para o seu novo desafio, isso seria insuficiente, mas seria bom repetir para sempre e dobrar a quantidade de memória usada a cada vez.
BenGoldberg

Respostas:


46

Funge-98 ( cfunge), 1 byte

9

Eu teria postado isso antes, mas decidi testá-lo e demorou um pouco para que meu computador voltasse a um estado utilizável. cfungearmazena 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 empurra 9repetidamente; 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:

"NULL #(4

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, o Nreflete (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 a Nparte superior da pilha -, em seguida, o programa gira, carregando uma biblioteca com um nome de quatro letras ( 4(; a NULLbiblioteca faz parte de cfungebiblioteca padrão). NULLdefine todas as letras maiúsculas para refletir, de modo que Lreflete, o#pula a carga da biblioteca no caminho de volta, 4empurra 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).


2
Eu só vou aceitar isso ...
tbodt

É necessário que o número seja 9? Também funcionaria se fosse 5?
Tbodt 01/12/19

Tudo o que for enviado para a pilha funciona (exceto possivelmente 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 peguei 9arbitrariamente.

22
Unaccepting porque eu quero que a minha reputação de ainda estar 666.
tbodt

7
@tbodt Não é um motivo real para não aceitar. Se você quiser, colocarei sua pergunta em -1. Então, quando você aceitar, terá 703 ainda (observe que você tem 703 agora, não 666).
NoOneIsHere

30

Brainfuck, 5 bytes

+[>+]

Isso requer um intérprete que não tenha limite no comprimento da fita.


2
Eu tenho certeza que é + [> +] ou então ele simplesmente parava na primeira iteração. ;)
Pâris Douady

Você está certo, desculpe pelo erro de digitação.
vsz 01/12/19

40
Uma das raras vezes em que uma solução brainfuck é competitivo ...
FlipTack

@ Flp.Tkc Mas ainda perde. Talvez ele vai ganhar um dia ...
NoOneIsHere

6
@SeeOneRhino: Ele já venceu uma vez, superando todos os idiomas do golfe> codegolf.stackexchange.com/questions/8915/…
vsz

22

Bash + coreutils, 5

ou

Ruby, 5

`yes`

yesproduz uma saída sem fim. Colocar yesbackticks 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.


7
Eu estava prestes a escrever o mesmo e chamar de um programa Ruby.
GB

11
e perl, eu acho.
abligh

18

Python, 16 bytes

Mantém o aninhamento aaté que seja atingido um erro:

a=0
while 1:a=a,

As primeiras iterações (como tuplas) são assim:

0
(0,)
((0,),)
(((0,),),)

e assim por diante.


18

> <> (Peixe), 1 byte

0

Experimente aqui!

0 pode realmente ser substituído por qualquer número hexadecimal 1-f.

Explicação

0in> <> simplesmente cria um codebox 1x1 para o peixe nadar. Ele constantemente adiciona um 0na pilha, nada direito, o que volta ao redor 0, adicionando-o novamente à pilha. Isso continuará para sempre.


2
Agora, estou pensando em quantas outras linguagens bidimensionais isso funciona. A maioria delas é baseada em pilha, afinal.

11
Quase funciona no Cubix , mas requer um líder .(ou qualquer caractere que não seja um espaço em branco) para mover 0a linha de execução.
ETHproductions

11
Funciona em Ouroboros , mas não da mesma maneira: o intérprete tenta ler 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 seria a(empurra 10 infinitamente).
DLosc

12

Java 101 bytes

class A{public void finalize(){new A();new A();}public static void main(String[]a){for(new A();;);}}

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


bem, eu me sinto meio boba por não seguir o óbvio agora, haha. Atrevo-me a dizer que isso é mais elegante que o meu #
Poke

11
sim, o seu código de me lembrava desse fato com o finalize () @poke
masterX244

Eu acho que você poderia torná-lo mais curto, substituindo principal com um inicializador estático
tbodt

só funciona até java6 e eu só tenho versões superiores ao redor
masterX244

2
haha usando o coletor de lixo para causar um vazamento! grande ideia :)
Mark K Cowan

12

Perl, 12 bytes

{$"x=9;redo}

Em perl, o xoperador, com uma sequência à esquerda e um número à direita, produz uma sequência repetida. Então "abc" x 3avalia 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 redooperador 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 :).


Você chegou antes de mim! E o seu é três bytes mais curto.
Gabriel Benamy

11
Era apenas uma questão de pesquisar neste site pelo menor loop :). Além disso, eu tinha inicialmente $_.=7no meu loop, mas percebi que, se eu pudesse usá- x=lo, a memória ficaria muito mais rápida e, em seguida, corri perldoc perlvarpara escolher algo adequado.
precisa saber é o seguinte

{$^O++;redo}é um byte mais curto quando ^Oé um único chr(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.
Oleg V. Volkov

11

sed, 5 bytes

Golfe

H;G;D

Uso (qualquer entrada serve)

sed 'H;G;D' <<<""

Explicado

#Append a newline to the contents of the hold space, 
#and then append the contents of the pattern space to that of the hold space.
H

#Append a newline to the contents of the pattern space, 
#and then append the contents of the hold space to that of the pattern space. 
G

#Delete text in the pattern space up to the first newline, 
#and restart cycle with the resultant pattern space.
D

Captura de tela

insira a descrição da imagem aqui

Experimente Online!


2
Estritamente falando, isso é GNU sed (ponto e vírgula não é padrão), mas uma nova linha funcionaria tão bem quanto o ponto e vírgula de qualquer maneira.
R ..

10

Haskell, 23 19 bytes

main=print$sum[0..]

Imprimir a soma de uma lista infinita


Essa é uma boa maneira de aplicar a avaliação e também é muito compacta. +1
Esolanging Fruit

um compilador poderia muito bem executar isso na memória O (1). No GHC, sumé definido como foldl (+) 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?
Will Ness

@WillNess Qual poderia ser a resposta? sumnão saberá antecipadamente que a lista é infinita e, printna soma, deve ser avaliada primeiro. E sim, eu o compilei com otimizações
Angs 04/12/16

não haveria resposta; mas o cálculo seria executado no espaço O (1). Opa, parece que, por causa do padrão Integer, os números são ilimitados e a memória obtida pelo resultado atual do bignum realmente aumentaria.
Will Ness

11
apenas para esclarecer, o que eu quis dizer foi que o cálculo de sum xs = foldl (+) 0 xspode ser executado em pilha constante, como qualquer loop imperativo . foldl' (+) 0 xscertamente vai. Portanto, a única coisa que aloca memória com certeza é o resultado intermediário do bignum.
Will Ness

9

C ++ (usando o compilador g ++), 27 23 15 bytes

Agradeç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.

main(){main();}

Solução alternativa

Esta solução realmente vaza memória.

main(){for(;;new int);}

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.

==2582== LEAK SUMMARY:
==2582==    definitely lost: 15,104,008 bytes in 3,776,002 blocks
==2582==    indirectly lost: 0 bytes in 0 blocks
==2582==      possibly lost: 16 bytes in 4 blocks
==2582==    still reachable: 4 bytes in 1 blocks
==2582==         suppressed: 0 bytes in 0 blocks

3
O título é enganoso; a pergunta diz para "escrever um programa que é executado para sempre e aloca memória continuamente".
NobodyNada - Reinstate Monica

Ah, eu não sabia que você já havia enviado uma resposta quando enviei a minha.
neop

11
@ Neop Bem, eu não sabia que você poderia omitir o int até que eu vi o seu, então obrigado!
Wheat Wizard

2
Não C++, apenas o dialeto do g ++: o C ++ proíbe chamar main; C ++ requer int main...declaração. Mas a solução ainda é puro :-)
Martin Ba

11
De fato, o C ++ proíbe chamadas main.
R ..

9

JAVA, 81 79 78 bytes

JAVA (HotSpot) 71 70 bytes

Mais curtas do que as outras respostas Java no momento em que publiquei (81, depois 79 bytes):

class A{public static void main(String[]a){String x="1";for(;;)x+=x.intern();}}

Conforme sugerido por @Olivier Grégoire, um outro byte pode ser salvo:

class A{public static void main(String[]a){for(String x="1";;)x+=x.intern();}}

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+=xobras também:

class A{public static void main(String[]a){String x="1";for(;;)x+=x;}}

O que também pode se beneficiar da dica de @Olivier Grégoire:

class A{public static void main(String[]a){for(String x="1";;)x+=x;}}

Minhas únicas dúvidas sobre isso é que não é garantido alocar dados no heap , pois uma JVM eficiente pode facilmente perceber que xnunca escapa à função local. O uso intern()evita essa preocupação, porque as seqüências internas acabam sendo armazenadas em um campo estático. No entanto, o HotSpot gera um OutOfMemoryErrorcódigo para esse código, então acho que está tudo bem.

Atualização: @Olivier Gregoire também apontou que o x+=xcódigo pode ser executado em StringIndexOutOfBoundsExceptionvez de OOMquando há muita memória disponível. Isso ocorre porque o Java usa o inttipo de 32 bits para indexar matrizes (e Strings são apenas matrizes de char). Isso não afeta a x+=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.


Bem-vindo ao PPCG! Eu não conheço Java muito bem; o que aconteceria se você acabasse de fazer x+=x;?
ETHproductions

você pode raspar um ponto e vírgula fora, colocando o x+=x.intern()atrás do último ponto e vírgula do loop for
masterX244

Boa resposta. Eu sabia que tinha que haver algo com cordas, internmas 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.
Puxa

Se sua resposta depende de uma implementação específica de Java e não necessariamente é portátil para todas as implementações de Java, você pode colocar as informações no título (por exemplo # 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.

11
humm ... x+=x;não esgota toda a memória. Com 64 GB, recebo um StringIndexOutOfBoundsException, não um OOM. Com .intern()eu ainda recebo o OOM.
Olivier Grégoire

8

Perl 6 , 13 bytes

@= eager 0..*

Explicação:

@ = armazena o resultado em uma matriz sem nome

eager faça a seguinte lista ansiosa

0 .. * faixa infinita começando em zero


8

///, 7 bytes

/a/aa/a

Substitua constantemente apor aaad nauseum.


12
*aad naauseum
timothymh

11
* ad nauseam=>aad naauseaam
Aaron

Que tal //a/? Isso parece substituir para sempre `` (nada) por a, mas não tenho certeza se isso está exatamente especificado.
Cedric Reichenbach

6

Python 3, 16 bytes

i=9
while 1:i*=i

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).


O título implica que a memória deve vazar. Mas isso realmente não vaza memória. O autor provavelmente deve esclarecer.
Wheat Wizard

6

Ferrugem, 46 bytes

fn main(){loop{std::mem::forget(Box::new(1))}}

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.


6

Conjunto hexagonal TI-83, 7 bytes

PROGRAM:M
:AsmPrgm
:EF6A4E
:C3959D
:C9

Cria appvars indefinidamente até que um ERR:MEMORYseja lançado pelo sistema operacional. Corra com Asm(prgmM). Eu conto cada par de dígitos hexadecimais como um byte.


6

Python, 8 bytes

2**9**99

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 é

>>> 9**99.
2.9512665430652752e+94

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).


5

Geléia , 3 2 bytes

-1 byte graças a Dennis ( Wenvoltó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 ...


Se eu entendo as regras corretamente, ‘ßdeve ser suficiente.
Dennis

Isso realmente "aloca memória continuamente" (pensando em Python mantendo alocação constante para pequenas entradas).
Jonathan Allan

11
Justo. ainda deve caber a conta embora.
Dennis

5

Java 7, 106 bytes

class A{public void finalize(){for(;;)Thread.yield();}public static void main(String[]a){for(;;)new A();}}

Menos Golfe

class A{
    @Override
    public void finalize(){
        for(;;) {
            Thread.yield();
        }
    }
    public static void main(String[]a){
        for(;;){
            new A();
        }
    }
}

O finalizemé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. No mainloop, crio novos objetos que nunca serão limpos e, eventualmente, isso consumirá toda a memória disponível.

Java 7 (alternativa divertida), 216 bytes

import sun.misc.*;class A{public static void main(String[]a)throws Exception{java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(1>0);for(;;)((Unsafe)f.get(null)).allocateMemory(9);}}

Menos Golfe

import sun.misc.*;
class A{
    public static void main(String[]a)throws Exception{
        java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe u = (Unsafe)f.get(null);
        for(;;) {
            u.allocateMemory(9);
        }
    }
}

Este é mais divertido do que qualquer outra coisa. Esta resposta faz uso da Unsafebiblioteca Sun, que é uma API interna não documentada. Pode ser necessário alterar as configurações do compilador para permitir APIs restritas. Unsafe.allocateMemoryaloca 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ê chamar Unsafe.freeMemoryou até que a jvm fique sem memória.


11
Estava pensando se eu veria Java aqui.
Magic Octopus Urn

O primeiro não funciona apenas se o coletor de lixo estiver sendo executado em um encadeamento separado?
precisa saber é

@ tbodt sim, mas eu não acredito que isso nunca seja o caso. A coleta de lixo ocorre em um encadeamento daemon chamado coletor de lixo
Poke

@ Poké é garantido? se não for a resposta ainda é bom, mas você deve esclarecer que ele só funciona se as pistas de coletor de lixo em seu próprio segmento
tbodt

@ tbodt Acho que sim, mas não tenho certeza, honestamente.
puxão

5

Haskell, 24 bytes

f x=f$x*x
main=pure$!f 9

O principal problema em Haskell é vencer a preguiça. mainprecisa ter algum IOtipo, então simplesmente chamar main=f 9não funcionaria. Usar main=pure(f 9)eleva o tipo de f 9para um IOtipo. No entanto, o uso de construções como main=pure 9não faz nada, 9é retornado ou exibido em lugar nenhum, mas simplesmente descartado; portanto, não há necessidade de avaliar o argumento de pure, portanto main=pure(f 9), não faz com que nenhuma memória seja alocada como fnão é chamada. Para impor a avaliação, o $!operador existe. Simplesmente aplica uma função a um argumento, mas avalia o argumento primeiro. Portanto, usar main=pure$!f 9avalia fe, portanto, aloca continuamente mais memória.


Quando compilado, o tempo de execução detecta o loop e quebras de execução
Angs

@ Angs eu compilei com o ghc no windows e ele fica felizmente alocando memória ... eu parei com 3GB.
Laikoni

Usando f x=f xobras também, certo? (−2 bytes)
wchargin

@chargin Acho que não, f x=f xproduz um loop infinito, mas sem alocar nova memória.
Laikoni

Bom, causando a perda de memória pelos cálculos de bignum! f!x=x*f(x*x)deve torná-lo à prova de otimizações.
Will Ness

5

dc, 7 bytes

[ddx]dx

[ddx]envia uma string contendo "ddx" para a pilha. dxduplica 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.


Espere, para que isso alocasse exponencialmente a memória se ela pudesse ser executada em paralelo?
HyperNeutrino 02/12/19

5

Haskell (usando o ghc 8.0.1), 11 bytes

m@main=m>>m

Recursão não-cauda. mainchama a si mesmo e depois a si próprio novamente.


Isso aloca na pilha ou na pilha? (Eu acredito que quer, ele pode muito bem depender do compilador Haskell em usos.)

11
@ ais523: depende. Haskell não tem pilha de chamadas . O sistema de tempo de execução RTS possui uma área de memória para correspondência de padrões, também chamada de "pilha". Essa pilha está alocada no heap. Honestamente, não sei o que está acontecendo aqui, porque o programa falha com 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.
1/16

11
@ ais523: parece haver um erro nas informações de memória da mensagem de erro do ghc, por isso é difícil dizer exatamente o que acontece.
nimi

Compilado em GHC 7.10.3 no Ubuntu, isso parece leva uma quantidade constante de memória mesmo quando otimizações estão desativadas
Angs

@ Angs: hmm, eu uso o ghc 8.0.1 no MacOS. Vou editar isso em.
nimi

5

C (linux), 23 bytes

main(){while(sbrk(9));}

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 no VIRTcampo de topsaí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

main(){while(malloc(9));}

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 pelos malloc()internos.


Com o malloc, você não está gravando diretamente na memória, pois o malloc não inicializa nada. A memória é alocada apenas porque o malloc precisa de algum armazenamento interno para gerenciar a memória. Portanto, a resposta não é realmente padrão, mas acho que funciona em qualquer lugar.
Antzi

@Antzi Yes. No entanto, acho que isso ainda funciona, porque, embora a memória do usuário possa não ser realmente alocada antes de ser gravada, cada malloc()bloco ed ainda deve ter seu próprio espaço alocado real. Isso funciona no macOS e no Ubuntu.
Digital Trauma

A condição na questão de cada página que está sendo escrita é bastante sem sentido; mesmo que você queira presumir que um sistema operacional não faz contabilidade de consolidação adequada, independentemente dos detalhes da implementação, há necessariamente uma quantidade diferente de zero de contabilidade necessária por alocação. Seja adjacente à alocação (fazendo com que as páginas sejam tocadas) ou não, acabará consumindo quantidades arbitrárias de memória para contabilidade com (necessariamente) dados diferentes de zero.
R ..

Você pode obtê-lo um byte menor 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 no main...
R. ..

Se você substituir malloc (9) por calloc (9,9), haverá memória suficiente alocada para 9 instâncias de um bloco de 9 bytes (portanto, entre 81 e 144 bytes, dependendo do alinhamento. No entanto, e mais importante, calloc ( ) zerará o bloco de memória, forçando o SO subjacente a alocar armazenamento a ele.
CSM

5

Perl, 4 bytes

do$0

Executa-se, no intérprete atual. Quando concluída, a execução retorna ao script de chamada, que requer uma pilha de chamadas.


Bonito e curto, embora não perca memória rapidamente como a minha.
BenGoldberg

4

Raquete, 13 bytes

(let l()(l)1)

Não tenho certeza se minha resposta se enquadra nessa pergunta. Informe-me se devo remover esta resposta.


Você pode explicar como isso funciona?
precisa saber é

11
ah, então está definindo lcomo uma função que faz recursão sem chamada de cauda. eu diria que conta.
precisa saber é

@tbodt sim, você está certo sobre o dinheiro
Winny

4

JavaScript 22 21 17 16 15 bytes

for(a=0;;)a=[a]

Economizou 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)

f=a=>f([a]);f()

11
No seu segundo exemplo com o ES6, você não poderia simplesmente fazer f=_=>f();f()? 12 bytes
mordido

@ mordido não tenho certeza. Se conta para explodir a pilha de chamadas, então aquela sem chamadas de cauda adequadas seria o caminho a seguir. Com o TCO, acho que não haveria memória vazada, haveria?
1/16

ambos explodem a pilha de chamadas para mim . Eu não estou realmente familiarizado com chamadas de cauda, ​​então não posso comentar sobre isso.
Mordido

11
ah eu vejo, eu não tinha certeza de como o seu estava vazando memória
mordido

11
Você pode remover a=0. A primeira iteração resultaria ema=[undefined]
Florent

4

Ruby, 11 bytes

loop{$*<<9}

Mantém empurrando 9para $*, que é uma matriz inicialmente segurando os argumentos de linha de comando para o processo de rubi.


4

05AB1E , 2 bytes

[A

Experimente online! Apenas continuará empurrando abcdefghijklmnopqrstuvwyxzpara a pilha por toda a eternidade.

Todas as soluções possíveis de 2 bytes:

[  # Infinite loop.
 A # Push alphabet.
 0 # Push 0.
 1 # Push 1.
 2 # Push 2.
 3 # Push 3.
 4 # Push 4.
 5 # Push 5.
 6 # Push 6.
 7 # Push 7.
 8 # Push 8.
 9 # Push 9.
 T # Push 10.
 X # Push 1.
 Y # Push 2.
 ® # Push -1.
 ¶ # Push \n.
 º # Push len(stack) > 0, so 0 once then 1 for eternity.
 ð # Push a space.
 õ # Push an empty string.
 ¾ # Push 0.
 ¯ # Push [].
 M # Push -inf.
 ) # Wrap current stack in an array.

Muito completo! Agradável.
timothymh

3

Python, 35 bytes

def f(a=[]):a.append(a)
while 1:f()

a nunca é liberado e fica maior até você atingir um MemoryError

Você pode ver a execução no Python Tutor .


11
Você pode fazer a+=a,?
Cyoce 02/12/16

Não há necessidade de uma função, aqui está o meu golf dela
FlipTack 2/16/16

@ Flp.Tkc a pergunta foi alterada depois que eu escrevi esta resposta, eu teria feito o que você fez (+ - dois caracteres) se estivesse no formato atual.
Noelkd

3

TI-BASIC, 8

:Lbl A
:While 1
:Goto A

(todos os tokens de 1 byte e duas novas linhas)

Isso vaza memória continuamente porque o fluxo de controle estruturado, como o Whilefechamento antecipado por um Ende empurra algo na pilha (não a pilha do SO, uma pilha separada na memória de pilha) para acompanhar isso. Mas aqui estamos usando Gotopara deixar o loop (para que não Endseja executado para remover a coisa da pilha), ela Whileé vista novamente, a coisa é empurrada novamente, etc. Portanto, ela continua pressionando-a até vocêERR:MEMORY

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.