Crea una perdita di memoria, senza bombe a forcella [chiuso]


54

Il tuo compito è creare una perdita di memoria . Questo è un programma che utilizza un sacco di memoria, fino a quando il computer si esaurisce e deve fare qualche scambio per salvarsi dall'esaurirsi. L'unico modo per liberare la memoria è uccidere il programma nel task manager o usare un kill della riga di comando come taskkill /im yourprogram /f(in Windows) o anche riavviare il computer. La semplice chiusura dell'app non dovrebbe impedirle di continuare ad accumulare memoria.

Regole:

  1. Le bombe a forcella di qualsiasi tipo sono vietate. Ciò significa che la famigerata linea Bash:(){ :|:&};: è vietata!

  2. L'applicazione deve essere solo a thread singolo. Ciò implica la regola della bomba a forcella.

  3. Il programma non deve eseguire altri programmi. Ciò significa che non puoi semplicemente fare qualcosa del genere run(memoryfiller.exe). L'unica eccezione a questo è i programmi in bundle con il tuo sistema operativo o lingua, che non sono progettati principalmente per consumare memoria (cioè hanno un altro scopo). Ciò significa che le cose piacciono cate ln -ssono permesse.

  4. Puoi occupare tutta la memoria che desideri. Più meglio è.

  5. Il codice deve essere spiegato completamente.

In bocca al lupo. Questo è un concorso di popolarità, quindi vince il codice con il maggior numero di voti dopo 10 giorni dalla data richiesta!


8
"Chiuderlo dovrebbe comunque renderlo memoria di maiale" - se un programma è un eseguibile di shell (come la maggior parte delle versioni di Windows degli interpreti del linguaggio di scripting), chiudere la sua finestra ucciderà il programma.
mniip,

54
Non è solo questo while(1)malloc(999);?
Maniglia della porta

10
Non sono sicuro che "Chiuderlo dovrebbe comunque renderlo memoria di maiale" è compatibile con "L'applicazione deve essere solo a thread singolo". Se nessun thread ha un pezzo di memoria, il sistema operativo può ripristinarlo, giusto?
aebabis

51
Basta eseguire Firefox 26 con alcune schede aperte in esecuzione flash per mezz'ora. Metterà il tuo computer in ginocchio.
Braden Best

1
@mniip. Questo è il punto centrale della sfida. Fare una sfida difficile. E maniglia. Volevo qualcosa di diverso! ;)
George

Risposte:


78

finestre

L'API Win32 consente di allocare memoria in altri processi e quindi di leggere / scrivere quella memoria in remoto. Questo programma ha solo un thread, che utilizza per enumerare ogni processo in esecuzione sul sistema, quindi allocare ripetutamente buffer da 1 MB in ciascun processo fino a quando l'allocazione non riesce. Quando termina con un processo, passa al successivo. Le allocazioni non vengono rilasciate al termine del programma chiamante, solo quando / se termina ciascun processo di destinazione. Ciò blocca una VM Windows 7 da 2 GB in circa 10 secondi. Richiede l'esecuzione come amministratore.

Compilare: 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 è malvagio.
tomsmeding

4
Ho bisogno di chiudere stanotte. Ci provo;)
George,

1
"(in esecuzione come utente normale, non utilizzando i privilegi di amministratore" - non sono sicuro di questo, è necessario SeDebugPrivilege che per impostazione predefinita non è presente nel token dell'utente normale
rkosegi

@rkosegi Grazie, risolto.
Andrew Medico

14
+1 Questo merita molti voti dato che finora è l' unica risposta che soddisfa l'originale. Chiuderlo dovrebbe comunque renderlo necessario. Soluzione molto creativa :-)
Daniel

72

Giava

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();
    } 
  }
}

Spiegazione

Si potrebbe supporre che dal momento che non ci sono riferimenti nel codice (a parte count, che è possibile ignorare in modo sicuro), non può fuoriuscire. Tuttavia, il finalizzatore crea due nuovi Idra e, sebbene non contenga riferimenti nemmeno per questi, resteranno in attesa fino alla finalizzazione. Ciò significa che il programma perde memoria solo durante la garbage collection, quindi le chiamate a System.gc()e System.runFinalization().


7
@TimS. dov'è il tuo Dio adesso?!?
Cruncher,

Sono System.gc()e System.runFinalization()necessari? Cioè a volte gc verrà eseguito casualmente o devi riempire un po 'di memoria o chiamare gc?
Cruncher,

4
In un programma tipico, System.gc()e System.runFinalization()non sarebbe necessario. La raccolta dei rifiuti avverrebbe naturalmente a causa della pressione della memoria. Tuttavia, in questa applicazione non c'è pressione della memoria fino a quando non inizia l'esecuzione della garbage collection. Ho pensato di introdurne alcuni artificialmente (ad esempio, spostandomi new Hydra()all'interno del ciclo), ma ho pensato che fosse più malvagio.
James_pic,

1
Sì, non ho prestato molta attenzione al avvertimento "La chiusura dovrebbe comunque renderlo memoria di maiale", in quanto non sembrava significativo (a parte gli hack del sistema operativo come @ german_guy's). Java fa sempre girare un thread di finalizzazione, quindi forse non c'è modo per un'applicazione Java di obbedire alla regola # 2.
James_pic,

1
Sui sistemi Unix, non puoi bloccare SIGKILL (segnale 9), quindi non puoi rendere il tuo programma inarrestabile (beh, tranne se riesci a portarlo in uno stato di attesa ininterrotto ... quindi forse uccidere in remoto un server NFS di cui file l'accesso potrebbe funzionare ;-))
celtschk

37

C

Usando il linguaggio di programmazione C e testato con kernel Linux 2.6.32-49-generico e libc-2.11.1.so.

L'unico modo per liberare la memoria è uccidere il programma in Task Manager o usare taskkill / im yourprogram / f o anche riavviare il PC.

Ciò si ottiene bloccando qualsiasi segnale ad eccezione di SIGKILL e SIGSTOP.

Chiuderlo dovrebbe comunque renderlo memoria di maiale.

Questo in realtà mi ha confuso ... Uccidere o chiudere entrambi comporta la fine del processo, consentendo al sistema operativo di rivendicare qualsiasi memoria allocata dal processo. Ma poi ho pensato che chiudendolo potresti voler chiudere il terminale o qualsiasi altro processo genitore che esegue il processo di perdita di memoria. Se ho capito bene, ho risolto questo problema bloccando qualsiasi segnale, il che trasforma il processo in un demone al termine del processo padre. In questo modo è possibile chiudere il terminale in cui è in esecuzione il processo e questo continuerà a funzionare e procederà alla perdita di memoria.

Le bombe a forcella di qualsiasi tipo sono vietate. Ciò significa che famigerato bash: () {: |: &} ;: è vietato!

Il processo non si biforca.

L'applicazione deve essere a thread singolo. Ciò implica la regola della bomba a forcella

Non vengono generati nuovi thread.

Il programma non deve eseguire altri programmi. Ciò significa che non puoi semplicemente fare qualcosa di simile a run (memoryfiller.exe)

Non vengono generati nuovi processi.

Puoi occupare tutta la memoria che desideri. Più meglio è.

Per quanto il sistema operativo può fornire.

Il codice deve essere spiegato completamente.

Aggiunti commenti alla fonte.

E finalmente ecco il codice:

#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;
}

Per chiunque sia interessato a ciò che accade se si mantiene questo programma in esecuzione: sul mio sistema di test con 2 GB di RAM e 4 GB di spazio di swap, sono stati necessari circa 10 minuti per riempire la RAM e scambiare. Il killer OOM ha iniziato il suo lavoro e tre minuti dopo sono stati uccisi tutti i processi. Anche il mouse, la tastiera e il display sono stati eliminati dal sistema. /var/log/kern.log non mostra informazioni utili, ad eccezione dei processi che sono stati uccisi.


Ho modificato la fonte per fare in modo che l'assassino di Oom ignorasse il processo e uccidesse invece processi innocenti per liberare memoria.
Foobar

5
Per chiunque sia interessato a ciò che accade se si mantiene questo programma in esecuzione: sul mio sistema di test con 2 GB di RAM e 4 GB di spazio di swap, sono stati necessari circa 10 minuti per riempire la RAM e scambiare. Il killer OOM ha iniziato il suo lavoro e tre minuti dopo sono stati uccisi tutti i processi. Anche il mouse, la tastiera e il display sono stati eliminati dal sistema. /var/log/kern.log non mostra informazioni utili, ad eccezione dei processi che sono stati uccisi.
foobar

Haha, è meraviglioso! Dovresti modificare quella descrizione nella tua risposta. +1
Maniglia della porta

1
Non ho effettuato il downgrade, ma sarebbe bello se il codice potesse essere formattato, quindi non è necessario lo scorrimento orizzontale per leggere i commenti.
Paŭlo Ebermann,

2
+1 per 1) causando l'uccisione dei processi che consegnano i dispositivi di input / output e 2) creando un programma difficile da tracciare dai registri. Si tratta di livelli malvagi di baffi che arricciano.
Kevin - Ripristina Monica il

29

Pure Bash

Non una bomba, prometto:

:(){ : $@$@;};: :

Assomiglia molto a una bomba a forcella e usa una tecnica ricorsiva simile, ma senza forcelle. Ovviamente questo eseguirà la tua shell senza memoria, quindi ti consigliamo di avviare una nuova shell prima di incollare questo comando.

  • Definire una funzione chiamata :
  • La funzione si chiama semplicemente in modo ricorsivo con $@(lista arg) raddoppiata
  • Dopo la definizione della funzione, la :funzione viene chiamata con un arg iniziale:

Produzione:

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

In una precedente modifica di questa risposta l'ho fatto a=$(yes), ma ho notato la regola "Il programma non deve eseguire altri programmi", quindi ho bisogno di usare pure bashinvece senza chiamare coreutils o altro.


Eccone un altro:

PER FAVORE, NON ESEGUIRE QUESTO SU UNA MACCHINA DI PRODUZIONE

:(){ : <(:);};:

Ancora una volta, questa non è una bomba a forcella: tutto viene eseguito all'interno di un thread. Questo sembra mettere abbastanza in ginocchio la mia macchina virtuale Ubuntu, con poco spazio per il recupero, oltre al riavvio.

Come nella classica bomba a forcella, :()viene definita una funzione ricorsiva . Tuttavia, non effettua il fork delle chiamate a se stesso. Invece si chiama con un argomento, che è esso stesso chiamato in una sostituzione di processo . Poiché la sostituzione di processo funziona aprendo un descrittore di file /dev/fd/n, questo non solo consuma memoria di processo (bash), ma consumerà anche parte della memoria del kernel. Sulla mia macchina Ubuntu questo ha l'effetto di rendere inutilizzabile il gestore delle finestre dopo alcuni secondi, quindi poco dopo aver finito con questa schermata:

inserisci qui la descrizione dell'immagine

Fare clic su OKquindi per visualizzare questa schermata:

inserisci qui la descrizione dell'immagine

Nessuna di queste opzioni sembra essere di grande aiuto - a questo punto il riavvio sembra essere l'unica buona opzione.


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

2
"L'unico modo per liberare la memoria è uccidere il programma in Task Manager o usare taskkill / im yourprogram / f o anche riavviare il PC. Chiuderlo dovrebbe comunque renderlo memoria di maiale." >> Il bash può essere terminato usando un SIGTERM, quindi non è necessario ucciderlo per fermarlo. Inoltre smette di funzionare quando il sistema esaurisce la memoria. Una volta terminata la bash, tramite SIGTERM o esaurendo la memoria, la memoria viene restituita al sistema operativo.
Foobar

Questo non funziona per me ... in un certo senso ... Riesco a vedere gradualmente scomparire la memoria, ma questo accade molto lentamente e può anche essere ucciso semplicemente premendo Ctrl + C. Funziona ora per 1 minuto ed è occupato per circa 1 GB. Ho una macchina MOLTO veloce ... ma non dovrebbe importare, vero?
Stefanos Kalantzis,

In risposta al mio commento: il comando ha effettivamente ucciso la bash dopo circa 2 minuti e 49 secondi. Inizialmente pensavo che si sarebbe istantaneo sulla base di questa risposta.
Stefanos Kalantzis,

@StefanosKalantzis Grazie per i tuoi commenti. Mi ha fatto pensare un po 'di più e ho appena trovato uno snippet di shell ancora più malvagio - vedi modifica.
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;"/>

Quindi passare il documento a un parser XML che non esegue il rilevamento del ciclo di riferimento dell'entità / ricorsione. Ad esempio, xpathincluso con perl:

xpath boom.xml /

Come funziona:

  1. Il parser incontra <boom a="&a;">
  2. Il parser si espande "&a;"in"&b;&b;"
  3. Il parser espande uno degli "&b;"in "&c;&c;"(al ritorno espande l'altro "&b;")
  4. Il parser espande una delle "&c;"ecc ...

Se si potesse verificare la piena espansione, ci sarebbe un'espansione 2 ^ 52 di "ka-boom!". Supponendo 2 byte per carattere, proverà a utilizzare 64 PiB. L'espansione va "ka-boom!" alla volta, quindi di solito puoi guardarlo consumare tutta la memoria in alto.

Questo va con vari nomi, buona panoramica qui: http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion


3
Essenzialmente una copia di miliardi di risate
Cole Johnson,

@ColeJohnson Sì, è tutto! Ho contribuito al progetto di classificazione delle minacce WASC, quindi mi sono sentito obbligato a indicare WASC piuttosto che Wikipedia. :)
ɲeuroburɳ

22

C ++

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

Questo codice è stato inaspettato! Ha appeso il mio computer mentre il task manager era aperto e ha mostrato che ci sono voluti 890 Mb di memoria in 1 secondo, quindi si è bloccato. Non so come funzioni, forse continua a dare memoria a una variabile. Per esplorare più di questo codice ho aggiunto un'istruzione delete a;e ogni cosa andava bene durante il test (nessuna sospensione) Quindi, penso che il pezzo di memoria sia dato (a causa di new int) e quindi riportato (a causa di delete a) allo spazio libero nel nuovo codice seguente.

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

Quindi, concludo che NESSUNA RAM IN QUESTO MONDO PUO 'MANEGGIARE QUESTO CODICE !!!

EDIT : Ma molti processori per esempio intel core 2 duonon possono gestire questo codice ma
intel core i-seriespossono (ha funzionato per me ...)

Ricorda che la risposta alla domanda è il 1 ° codice, il secondo è per spiegazione.


9
Bene, il compilatore pensa che continuerai a usare il new intanche se hai sovrascritto il puntatore, quindi non puoi mai accedervi di nuovo ... Quindi non viene chiamata la spazzatura e riempi la memoria più velocemente di quanto un bambino grasso mangia birilli
David Wilkins

37
@DavidWilkins: ... questo è C ++, C ++ non ha garbage collector.
Phoshi,

32
Se per te è inaspettato che questo codice perda, penso che non dovresti usare C ++ fino a quando non lo impari meglio.
svick

1
@svick Ma non è anche come colpire il bersaglio per le freccette al buio! Ho avuto qualche idea che questo farà la domanda di lavoro desiderata.
Mukul Kumar,

15
@svick Come diavolo dovrebbe "imparare meglio" se "non dovrebbe usare C ++"?
Kevin,

16

BrainFuck

+[>+]

Spiegazione:

Per entrare nel loop aumenta la cella a 1. Passa alla cella successiva aumentandola a 1 fintanto che l'ultima cella era positiva.

Di solito un interprete BrainFuck è imperfetto dall'avere un limite rigido al numero di celle sul nastro, ma alcuni interpreti aggiungono celle in modo dinamico. Questi continueranno a consumare memoria fino a quando non sarà più da consumare.

beefè uno di questi interpreti ed è disponibile in Ubuntu Software Center e la mia esecuzione corrente su una macchina inutilizzata è iniziata 29 ore fa e ha consumato 1 GB di RAM in quel momento. Ecco l'output ditop

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

Ha 4 GB di cache e 6 GB di swap, quindi credo che aggiornerò questa risposta con come è andata in circa 12 giorni.

AGGIORNAMENTO 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    

AGGIORNAMENTO 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   

Quindi è in esecuzione da 10 giorni. Sembra che sarà in esecuzione per almeno altri 10 prima che accada qualcosa di interessante.


Bello e breve.
nrubin29,

15

C e POSIX

Qui sto cercando una soluzione altamente portatile. Il problema è che il C puro non sembra avere un modo per dire al sistema operativo che la memoria dovrebbe rimanere allocata dopo la chiusura del programma. Quindi mi permetto di usare POSIX; la maggior parte dei sistemi operativi ha qualche pretesa di compatibilità POSIX tra cui Windows, Linux e MacOS X. Tuttavia, l'ho testato solo su Ubuntu 12.04 a 32 bit. Non richiede autorizzazioni per superutente.

Questa soluzione è essenzialmente la while(1){malloc(1);}soluzione tradizionale . Tuttavia, invece di malloc, utilizza le funzioni di memoria condivisa POSIX. Poiché assegna un identificatore di memoria condivisa a ciascuna allocazione, è ancora possibile accedere alla memoria una volta terminato il processo. Quindi il kernel non può liberare la memoria.

#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*/
  }
}

Risposta C migliore e più brillante IMO. +1
syb0rg

1
Ben fatto. La prima soluzione che mi è venuta in mente è stata quella di Andrew Medico, ma poiché ciò non è possibile su Linux e poiché non mi piace la programmazione di Windows, volevo passare attraverso la memoria condivisa, ma non riuscivo a ricordare i nomi delle funzioni POSIX. Grazie per avermi ricordato di loro;) Tutto quello che ho trovato sono state solo cose mmap che non sono state mappate al termine del processo ...
foobar

14

C #

Dimenticando di annullare la sottoscrizione agli eventi prima che il gestore esca dall'ambito, .NET perderà la memoria fino a quando non genera 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;
    }
}

Spiegazione : All'interno del whileciclo, costruiamo un nuovo oggetto, facendo sì che il framework alloca più memoria, ma impediamo anche il Brilascio della nuova istanza quando esce dall'ambito assegnando un metodo di istanza a un evento in una classe diversa, il risultato è che la nuova istanza di Bdiventa irraggiungibile dal nostro codice, ma esiste ancora un riferimento, il che significa che il GC non lo rilascerà fino a quando non andrà oltre lo ascopo.

Gli eventi statici hanno la stessa trappola, dal momento che non escono mai dal campo di applicazione, vengono ripuliti solo al termine del processo, a meno che non si annulli l'iscrizione all'evento. Conserva sempre i tuoi riferimenti, gente!

using System;

class Program
{
    static event Action Event;

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

Quanto sopra funziona sulla stessa idea, il gestore diventa irraggiungibile una volta che il whileciclo esce dall'ambito, rendendo impossibile annullare l'iscrizione all'evento, il che significa che la memoria rimarrà lì fino al termine del programma. Gli eventi statici sono probabilmente più pericolosi degli eventi di istanza, perché puoi assicurarti che non escano mai dal campo di applicazione.

EDIT : Puoi anche fare lo stesso praticamente con qualsiasi altro oggetto, purché aggiungi un riferimento assicurando allo stesso tempo che non ci sia modo di liberarlo.

Ecco un esempio che utilizza oggetti e matrici statici.

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 );
    }
}

Le matrici continuano ad essere aggiunte all'elenco, ma non c'è modo di cancellare l'elenco senza modificare il codice, il che sarebbe impossibile per le applicazioni a sorgente chiuso. Aumentando il numero passato, si Leak.Addverificherà una perdita più rapida, se lo si imposta abbastanza in alto si tradurrà semplicemente in un OverflowException immediato.


10

bash (nessuna utility esterna)

Nessuna bomba a forcella qui.

Avvertenza: potrebbe uccidere la shell.

Sto solo cercando di creare una matrice di numeri interi come riferimento perché continuo a dimenticare l'aspetto di numeri interi.

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

Risultati in:

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

2
+1 per "perché continuo a dimenticare l'aspetto degli interi" :)
David Conrad,

8

J (7)

ATTENZIONE: Questo ha bloccato il mio sistema quando l'ho provato (Windows 8, J 8.01, nel terminale qt).

2#^:_[_
  • 2# raddoppia la lunghezza dell'argomento duplicando ogni elemento,
  • ^:_ trova il punto di correzione di una determinata funzione (ma non ce n'è uno in modo che si giri all'infinito),
  • [_lo chiama _come argomento.

8

Haskell (il numero di Graham)

È molto semplice: questo calcola il numero di Graham

A differenza di altri esempi qui, non funzionerà per sempre ... utilizzerà un sacco di CPU, ma teoricamente potrebbe terminare. se non fosse per il fatto che per memorizzare il numero ...

l'universo osservabile è troppo piccolo per contenere una normale rappresentazione digitale del numero di Graham, supponendo che ogni cifra occupi un volume di Planck .

(secondo 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

Quindi, l'idea è che la memoria sarà utilizzata da una (serie di sempre più) enormi Integer(s) (gli Integer di Haskell sono di dimensioni arbitrarie).

Se vuoi provarlo, potresti dover aumentare le dimensioni dello stack o caricarlo all'interno ghci.


2
Universo muto, non conforme allo standard Haskell per Integer. Perché non supporta dimensioni arbitrarie?
PyRulez,

6

Ispirato da @comintern.

Sostituzione / dev / null. Coinvolgente modalità subdola. Richiede intestazioni del kernel, modalità superutente e un compilatore funzionante.

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

Divertiti.

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

Codice sorgente:

#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);

Attenzione, questo potrebbe costringerti a riavviare!

Per rimuoverlo:

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

6

Rubino

Tutti sanno che somma (1 / n ^ 2) = pi ^ 2/6

Quindi posso definire una funzione di approssimazione:

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

p pi_approx.(100_000)

Naturalmente (1..infinity) si scatenerà.

Si noti tuttavia che l'uso di pigro renderebbe questo lavoro;)

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 caratteri (programma completo)

Non eseguirlo, altrimenti il ​​tuo sistema si bloccherà rapidamente!

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

La chiamata a malloc riserva 9 byte di memoria e richiede regolarmente nuove pagine di memoria dal sistema operativo. La memoria allocata da malloc viene immediatamente trapelata poiché non viene memorizzato alcun puntatore all'indirizzo restituito. Una volta che il sistema ha esaurito la memoria (RAM e spazio di scambio) o è stato raggiunto il limite di memoria per il processo, il programma uscirà dal ciclo while e terminerà.


2
Non per molto - qualsiasi sistema ragionevolmente moderno dovrebbe avere un killer OOM che si avvii e uccida il processo. Almeno Ubuntu 12.04 lo fa.
Trauma digitale

1
Bene, ho bloccato Ubuntu 13.10 mentre provavo questo codice ...
Mathieu Rodic,

@DigitalTrauma Ad esempio FreeBSD ha un OOMK?
Ruslan,

1
main(){while(malloc(9));}salva altri 3 personaggi e riempie la mia memoria praticamente all'istante.
Gmatht,

@gmatht: grazie per il suggerimento! Ho modificato la risposta ... anche se mi è piaciuta l'idea di aumentare la dimensione del blocco su ogni loop.
Mathieu Rodic,

4

VBScript

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

Stiamo creando un dicionario che punta a se stesso. Quindi pensiamo di distruggere il dizionario impostandolo su Nothing. Tuttavia, il dizionario esiste ancora in memoria perché ha un riferimento (circolare) valido.

Il ciclo, ma anche il porco di memoria, fa bloccare il programma. Dopo l'arresto del programma, la memoria è ancora in uso. Il sistema può essere ripristinato solo riavviandolo.


Davvero? VBScript non usa solo VB.NET sotto il cofano? I riferimenti circolari non sono normalmente problemi per i garbage collector, ad eccezione delle semplici implementazioni del conteggio dei riferimenti e la chiusura del programma dovrebbe comportare il rilascio dell'intero heap, no?
David Conrad,

@DavidConrad Lo penseresti, ma ho dovuto riavviare la macchina ogni volta che ho studiato questo ed eseguito questo tipo di script.
AutomatedChaos,

1
VBScript precede VB.Net in modo significativo - non è una versione della riga di comando di VB.Net; è un sottoinsieme interpretato di Visual Basic legacy.
Chris J,

Grazie a tutti e due. Non avevo capito quale fosse la relazione tra VBScript e VB.NET.
David Conrad,

4

Sì e tmpfs

Perché scrivere un nuovo programma quando uno viene gratis con Ubuntu?

yes > /run/user/$UID/large_file_on_my_ramdisk

Come probabilmente saprai, o hai già indovinato, Ubuntu monta / run / user / per impostazione predefinita come tmpfs che è un tipo di disco RAM .

Non devi nemmeno chiuderlo. Si chiuderà educatamente, lasciando allocato un bel pezzo di memoria. Presumo che yessia un programma a thread singolo, a processo singolo che non chiama nessun altro (la scrittura su un disco RAM esistente è anche banalmente trasportabile nella lingua scelta).

Ha un bug minore: Ubuntu limita di default l'utente scrivibile tmpfs / run / 1000 a 100 MB per impostazione predefinita, quindi la funzione di decadimento dello swap potrebbe non essere supportata dalla tua macchina. Tuttavia, sono riuscito a risolvere il problema sul mio computer con la seguente soluzione rapida:

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

Non ho affatto una /run/userdirectory. Quale versione di Ubuntu usi e cosa hai installato per questo?
Ruslan,

Ubuntu Trusty Tahr (14.04). Nessuna installazione speciale richiesta.
Gmatht,

Per sapere se hai dei tmpfsfilesystem montati, puoi elencarli con df -t tmpfs. Il mio sistema Ubuntu ha un grande /run/shmdisponibile ...
Toby Speight

4

bash

Avviso: il seguente codice renderà il computer non avviabile.

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

Avviso: il codice precedente renderà il computer non avviabile.

Sostituisci / dev / sda con l'unità di avvio. Questo scrive E8 FD FF all'inizio del tuo settore di avvio. All'avvio, il BIOS legge il settore di avvio in memoria ed lo esegue. Quei codici operativi sono equivalenti a questo assembly:

label:
  call label

Questa è una ricorsione infinita, che alla fine causerà un overflow dello stack.


Nell'esempio di Assembly, potresti salvare un personaggio (supponendo che il nome "etichetta" sia necessario) usando jmpinvece dicall
SirPython

call lascia l'indirizzo di ritorno nello stack per ret. il salto non provocherebbe un overflow dello stack.
Jerry Jeremiah,

3

Haskell

main=print $ sum [0..]

Questo tenta di sommare i numeri di conteggio. Haskell valuta le somme parziali, diventa solo un'istruzione di aggiunta infinita. Se si esegue il compilatore con flag di ottimizzazione, potrebbe non funzionare.


3

bash

Dal momento che siamo in grado di utilizzare le utilità che non sono specificamente progettati per consumare la memoria, mi concentro su un programma di utilità per liberare la memoria: swapon. Questo è usato per consentire al kernel di liberare memoria scrivendo su disco.

Questo script esegue due ottimizzazioni: (1) Montando tmp come tmpfs (un tipo di disco RAM) per rendere / tmp più veloce e (2) creando un file di scambio per liberare memoria. Ognuno di questi è ragionevole da solo, ma se un utente negligente fa entrambi, allora imposta un ciclo di scambio: quando il sistema operativo cerca di scambiare pagine, scrive su tmpfs; questo fa in modo che tmpfs usi più memoria; ciò aumenta la pressione della memoria causando lo scambio di più pagine. Questo può richiedere alcuni minuti sulla mia VM, un sacco di tempo per guardare il sistema scavare in un buco usando top.

La chiusura del programma fa poca differenza poiché il programma stesso non assegna quasi memoria. In effetti non è banale liberare memoria poiché non è possibile liberare memoria smontando i file tmpfs prima di voi swapoffil file di scambio, e questo è difficile da fare fino a quando non avete liberato memoria.

Questa risposta potrebbe essere considerata un racconto cautelativo contro l'accecamento che applica trucchi interessanti dalla rete senza capirli.

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) { _;}

Utilizza riferimenti circolari. Il conteggio dei riferimenti per le variabili non raggiungerà mai 0 e i riferimenti non verranno mai raccolti in modo inutile.

Potrebbe essere necessario essere pazienti, ma è garantito che il sistema si blocchi. Il disco inizierà a girare più velocemente e potrebbero essere visibili fumi.


2

PHP (solo Linux):

Questo codice non è testato, dal momento che non ho un computer Linux con php in esecuzione.

Ma questa è la mia prova del concetto:

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

Questo riempirà la memoria con enormi immagini RGBA (10000x10000 pixel).

L'unico modo per spegnere questo bambino è spegnere il potere.

Il codice è tutto commentato.

Qualsiasi miglioramento, dubbio, errore o altro, utilizza la casella di commento qui sotto.


Qualcuno con accesso a Linux potrebbe testarlo? Grazie :)
George

Ho Linux, non sono sicuro di come funzionerà. Ho fornito lo schermo di stampa per la prima risposta, ma questa è una versione davvero vecchia di Linux cucciolo. Ubuntu è troppo lento per eseguire php. Forse testerò sul mio Android in seguito.
Ismael Miguel,

1
fallisce il punto di non chiamare un altro programma
Einacio,

Non sta chiamando un altro programma: sta chiamando lo stesso programma che ha avviato il file per lo stesso file.
Ismael Miguel,

2

Python - 56

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

Crea una classe, definisce un metodo per impostare gli attributi, imposta un attributo al suo interno e crea un'istanza iniziale di cui tenta quindi di impostare un attributo.

Una semplice funzione ricorsiva ( def f(x):f(x)) sembrava un po 'priva di immaginazione, quindi ho deciso di non chiamare mai effettivamente una funzione.

La gestione della memoria potrebbe catturare la profondità della ricorsione, ma dipende davvero dall'implementazione.

Se questa è una bomba, per favore dimmelo.


4
Questo fa sì che non esaurimento della memoria, solo una: RuntimeError: maximum recursion depth exceeded while calling a Python object. Anche l'impostazione del limite massimo di ricorsione con sys.setrecursionlimitquasi nessuna memoria viene utilizzata prima che si arresti in modo anomalo con un errore di segmentazione.
Bakuriu,

@Bakuriu Come ho detto, dipende molto dall'implementazione (ci sono implementazioni di Python che vengono convertite in C (++) e compilate, ad esempio Shedskin, Nuitka).
cjfaure,

2
Quindi indica per quale particolare implementazione stai scrivendo il codice. C'è una differenza tra le sfide in cui conta solo la sintassi e quindi l'implementazione non è rilevante, e le sfide che dipendono completamente da come viene implementata la lingua.
Bakuriu,

2

Perl

È semplice, ma mi andava di giocare a golf.

{$x=[$x];redo}

Dopo due iterazioni, $xcontiene un riferimento alla matrice contenente un riferimento alla matrice contenente undef.

L'uso della memoria è lineare nel tempo, con piccole allocazioni, ma ci sono voluti solo pochi secondi per rallentare gravemente il mio window manager sul mio sistema Ubuntu Linux. Mezzo minuto dopo l'assassino OOM se ne occupò.


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: utilizza setTimeout, che è definito come parte di Timer - HTML Living Standard .

Provalo su Mozilla Firefox (potresti incollarlo nella console degli sviluppatori). Firefox continua a consumare sempre più memoria e utilizza 100%la CPU su una macchina single-core (su una macchina a 4 core, come la mia, utilizza 25%la CPU). Ha anche il vantaggio di non poterlo fermare; se riesci ad aprire Task Manager, puoi uccidere Firefox con esso.


1
Utilizza il 100% di un core. Sul tuo processore quadcore, ciò comporta il 25% di utilizzo della CPU.
Iván Pérez,

@Electrosa Sì, hai assolutamente ragione. Ho aggiornato la mia risposta.
Spazzolino da denti

Questa non è una domanda di golf del codice, prova a rendere leggibile il tuo codice.
Paŭlo Ebermann,

@ PaŭloEbermann OK. Ho pubblicato una versione non giocata.
Spazzolino da denti

1

bash

Crea un file vuoto test
Sostituisci /dev/null/con questo file di testo

$ sudo mv test /dev/null

Funziona in modo simile alla risposta di @ Comintern. Tutto l'output a /dev/nullverrà ora aggiunto a questo file di testo, che col tempo diventerà enorme e causerà l'arresto anomalo del sistema.


1
Un file di grandi dimensioni non bloccherebbe il sistema. E supponendo una dimensione media del disco di 500 GB, ci vorrebbe molto tempo prima che il file si avvicinasse al riempimento del disco.
w4etwetewtwet

1
Sui sistemi in cui /devè a devtmpfs, può riempire e ostacolare il sistema. Immagino che sia l'intento di questa risposta.
Toby Speight,

1

Bash: 7 caratteri

Questa dovrebbe essere la soluzione bash più semplice. Niente forchette, niente imbrogli.

x=`yes`

Si consiglia di non eseguire questo come root.


Nota aggiuntiva: anche se si termina con Ctrl-C a metà strada, quindi unsetla variabile, la memoria rimane allocata fino a quando la shell non viene uccisa. Puoi vedere la carneficina top.
Riot

I miei test con bash 4.2.45 (1) mostrano che unset xlibera la memoria. pdksh libera anche la memoria, ma ksh93 non riesce a liberarla, e exitin ksh93 dump core.
kernigh,

Per me (bash 4.3.11 (1)), il display della memoria residente in alto per la shell genitore sale costantemente fino a quando non yesviene ucciso, a quel punto rimane semplicemente lì, unsetsenza alcun effetto. Ma questo è su un grande sistema di memoria e avere una variabile di diversi gigabyte non sembra disturbarlo (fino a quando non decide finalmente di uccidere la shell).
Riot

0

C

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

Bene, ci vuole una pagina di memoria dopo pagina e finalmente non c'è più memoria.


Quanto è universale una pagina di 4 KB?
Peter Mortensen,

@Peter 4K è spesso di dimensioni, ma non posso dire se è davvero universale, ma le dimensioni della pagina non hanno relazioni con una determinata domanda.
ST3

1
@ ST3: dovresti sporcare la pagina di memoria. La maggior parte dei sistemi operativi moderni utilizza la memoria virtuale e crea un record nella tabella della memoria virtuale quando si alloca memoria. Scrivere un singolo byte nella pagina di memoria costringerà già il sistema operativo a mappare la pagina di memoria virtuale sulla memoria fisica.
foobar


0

Rubino

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

Aggiunge all'infinito (ricorsivo!) Gli auto-riferimenti a se stesso.

Ho scoperto questo piccolo gioiello quando qualcuno ha rotto il mio sandbox Ruby con esso . : D

Demo degli aspetti ricorsivi di esso:

[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);}

Non-golfed

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

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

Ho corretto la mia voce per includere la chiamata dal principale.


Questo è un concorso di popolarità. Se il programma funziona, mantieni il principale e l'intestazione. va bene. Inoltre, potresti pubblicare una versione non giocata a golf? Grazie :)
George
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.