51
\$\begingroup\$

Write a program which runs forever and allocates more and more memory on the heap the longer it runs, at least until you reach the limit of the operating system on the amount of memory that can be allocated.

Many kernels won't actually reserve memory you allocate until you use it for something, so if your program is in C or some other low level language you'll have to make sure you write something to each page. If you're using an interpreted language, you're probably not going to have to worry about this.

Shortest code wins.

\$\endgroup\$
8
  • 13
    \$\begingroup\$ Is a stack overflow a valid solution? Does the memory have to be leaked or just allocated? \$\endgroup\$
    – Wheat Wizard
    Commented Dec 1, 2016 at 3:02
  • 1
    \$\begingroup\$ @WheatWizard The memory does not have to be leaked, but it has to be allocated faster than it is deallocated. \$\endgroup\$
    – tbodt
    Commented Dec 1, 2016 at 17:16
  • 2
    \$\begingroup\$ The one time I want my program to consume infinite memory, I can't get it to. (reduce conj [] (range)) (Clojure) gets up to 737mb, then just stops growing. Idk how it's not continually going up. It "thinks" I want to print the entire list at the end, so it shouldn't be throwing anything away. Very frustrating. \$\endgroup\$ Commented Dec 2, 2016 at 1:05
  • 15
    \$\begingroup\$ Note to self: Save code before testing. Introducing mem-leaks might crash IDE... \$\endgroup\$
    – steenbergh
    Commented Dec 2, 2016 at 9:03
  • 1
    \$\begingroup\$ I think you should add another golf challenge, similar but separate to this, requiring the program consume memory faster than a linear function of time. For the current challenge, looping forever and allocating a single byte should be fine. For your new challenge, that would be insufficient, but looping forever and doubling the amount of memory used each time would be ok. \$\endgroup\$ Commented Dec 17, 2016 at 18:30

71 Answers 71

3
\$\begingroup\$

PHP, 14 13 bytes

Saved a byte thanks to Alex Howansky

while($a.=1);

Indefinitely builds a string of 111111111111...

\$\endgroup\$
8
  • \$\begingroup\$ Which bizarre quirk of php does this exploit? \$\endgroup\$
    – tbodt
    Commented Dec 1, 2016 at 21:35
  • \$\begingroup\$ @tbodt $a[]=1 evaluates to something truthy so the while() loop equates to while(true) and just keeps looping and adding elements to the $a array. Not sure if this can be classified as a quirk though. Is identifying a quirk a requirement of your question? Would you like me to deconstruct my answer into multiple lines? \$\endgroup\$
    – MonkeyZeus
    Commented Dec 1, 2016 at 21:38
  • \$\begingroup\$ @tbodt Try it out at sandbox.onlinephpfunctions.com \$\endgroup\$
    – MonkeyZeus
    Commented Dec 1, 2016 at 21:52
  • 2
    \$\begingroup\$ You can chop a byte with while($a.=1); -- just build a huge string versus a huge array. \$\endgroup\$ Commented Dec 1, 2016 at 22:11
  • \$\begingroup\$ while($a.=1); indefinetely adds characters to a string. \$\endgroup\$
    – Titus
    Commented Dec 1, 2016 at 23:08
3
\$\begingroup\$

Python REPL, 13 bytes

9
while 1:_*9

The first line, 9, sets the built-in _ (last-integer) variable to 9. The infinite loop then keeps setting this to itself multiplied by 9.

Python integers have no upper limit, so this will keep growing until MemoryError.

This only works in the shell, where the _ variable is available. This is allowed by meta.

\$\endgroup\$
2
3
\$\begingroup\$

Mathematica, 16 bytes

For[i=0,0<1,i++]

Endlessly adds 1 to an arbitrary precision integer, causing its representation in memory to slowly grow.

Might also be the slowest submission since memory allocated only grows logarithmically with time. In fact, I've only let it run to several hundred billion, which barely alters allocated memory. So how do I know it grows without bound? Try the variant

For[i = 1, 0 < 1, i += i]

so that the memory usage is now linear in time... (If you want to watch i,

Monitor[For[i = 1, 0 < 1, i += i], i]

and notice, for instance, that the front end is allocating memory to hold the displayed values faster than the kernel is, because the binary representation is much less fluffy that the decimal representation and resulting graphical object. I suppose one could stress test one's 2D video acceleration by switching to the console interface and running the Monitor[] there... Heh.)

\$\endgroup\$
2
\$\begingroup\$

BASH, 2 bytes

$0

Parameter $0 is the filename of the script, so it will call itself forever.

\$\endgroup\$
4
  • 5
    \$\begingroup\$ This starts new processes repeatedly, instead of allocating memory in a single process, so I would say it doesn't count. \$\endgroup\$
    – tbodt
    Commented Dec 1, 2016 at 17:10
  • 1
    \$\begingroup\$ It could theoretically work on an operating system where processes share the heap with each other (some variants of uclinux, perhaps; DOS has a shared heap in 16-bit mode but I don't know that it has a bash implementation)? I don't think this can be valid without specifying an OS where it works, though. (Also, the process limit may be hit before the memory limit is.) \$\endgroup\$
    – user62131
    Commented Dec 1, 2016 at 18:43
  • \$\begingroup\$ I think $0|$0 works, but it's longer. \$\endgroup\$
    – Pavel
    Commented Dec 1, 2016 at 20:46
  • \$\begingroup\$ $0 $@$$& if you really wanted to kill your system, whilst not using compressed RAM. \$\endgroup\$
    – Stan Strum
    Commented Jan 29, 2018 at 20:50
2
\$\begingroup\$

WinDbg, 9 bytes

as/c a z1

This works by creating a string of infinite length. as /c Sets an alias (here called a) to the result of the following command(s): z 1 is an infinite do while loop that also prints a line when the while condition is true: redo [###] {redone_code}. So a will be set to a string like:

redo [1] z1
redo [2] z1
redo [3] z1
.
.
.
redo [23489723984] z1
.
.
.
\$\endgroup\$
2
\$\begingroup\$

Actually, 3 bytes

1W1

Try it online!

This is an infinite loop that pushes a 1 to the stack each time it runs. Actually is implemented in Python, and its stack is a deque, so, despite the name, all memory is dynamically allocated on the heap.

\$\endgroup\$
2
\$\begingroup\$

Microscript II, 3 bytes

1[s

Rough translation:

x=1
while x
  push x
\$\endgroup\$
2
\$\begingroup\$

SAS, 75 19

SAS doesn't really lend itself to golfing but I thought I'd have a go, and at least it beats Java some of the Java answers quite a lot of stuff, actually.

Original submission:

data;dcl hash h();h.definekey('i');h.definedone();a:i+1;h.add();goto a;run;

This creates a hash object and keeps adding new values to it until SAS runs out of memory. None of the hash operations fail prior to that point, so no need to capture any pesky return codes for them. SAS does have do loops, but goto saves a few characters.

New submission:

%macro a;%a%mend;%a

Much simpler - a trivial recursive macro. If left running for long enough, it eventually fails with an out of memory error. Both submissions assume that SAS was invoked with option memsize = 0, otherwise it will instead fail when it hits that limit if it is lower than the available system memory.

\$\endgroup\$
2
\$\begingroup\$

Ceylon, 55 54 35 bytes

shared void r(){variable Object x=0;while(0<1){x=[x];}}

This is a simple while loop, which creates a one-element tuple containing the previous value, i.e. an ever-growing linked list.

I get an OutOfMemoryError (with the default JVM settings on my computer) after:

real    5m42.727s
user    21m31.200s
sys     0m3.472s

5m42s (using 21 minutes of processor time, says time).

Even shorter is the "functional" approach (which in effect does exactly the same):

shared void r(){loop<Object>(0)((x)=>[x]).each(noop);}

Unfortunately I need the type parameter here, otherwise Ceylon assumes Integer (which is the type of 0) and complains that [0] is not an Integer.

The second version is much slower (I've let it run overnight):

real    197m26.677s
user    770m9.300s
sys     1m23.744s

A different approach is just filling a really big sequence of integers:

shared void r(){max((1:9^9)*.not);}

1:9^9 is a Measure<Integer> (an Iterable containing 9^9 elements, starting with 1), by itself not having lots of memory (just the two numbers). But the *.not attribute spread creates a big ArraySequence with the value of i.not for each element of the Iterable. We need to do something with the result (otherwise the compiler complains that this is not a statement), therefore the max(...). The max function is never called here, because this gives an OutOfMemoryError (with "GC overhead limit exceeded") after 6 minutes while trying to build and fill the array:

real    6m23.948s
user    23m46.956s
sys     0m5.200s
\$\endgroup\$
2
\$\begingroup\$

Labyrinth, 1 byte

_

This keeps pushing a 0 to the stack.

\$\endgroup\$
0
2
\$\begingroup\$

Brain-Flak, 10 bytes

(()){(())}

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ In the Ruby Brain-Flak interpreter just (()){()} Will actually work. This is because the Brain-Flak interpreter stores a unbounded variable called @current_value that is incremented by (). Each run of the loop will do nothing visible but will increment that value. As the value grows the program will allocate more and more memory. \$\endgroup\$
    – Wheat Wizard
    Commented Feb 15, 2017 at 15:02
2
\$\begingroup\$

V, 2 bytes

òé

You can try it online, even though it won't output anything.

This simply fills up the interal "buffer" with the ÿ character (0xFF) until the end of time.

\$\endgroup\$
2
\$\begingroup\$

C#, 109 bytes

public class P{static void Main({for(;;)System.Xml.Serialization.XmlSerializer.FromTypes(new[]{typeof(P)});}}

Cross posted from here because it answers this question nicely as well.

We found the idea behind this leak in production code and researching it leads to this article. The main problem is in this long quote from the article (read it for more info):

Searching my code for PurchaseOrder, I find this line of code in page_load of one of my pages XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder), new XmlRootAttribute(“”));

This would seem like a pretty innocent piece of code. We create an XMLSerializer for PurchaseOrder. But what happens under the covers?

If we take a look at the XmlSerializer constructor with Reflector we find that it calls this.tempAssembly = XmlSerializer.GenerateTempAssembly(this.mapping, type, defaultNamespace, location, evidence); which generates a temp (dynamic) assembly. So every time this code runs (i.e. every time the page is hit) it will generate a new assembly.

The reason it generates an assembly is that it needs to generate functions for serializing and deserializing and these need to reside somewhere.

Ok, fine… it creates an assembly, so what? When we’re done with it, it should just disappear right?

Well… an assembly is not an object on the GC Heap, the GC is really unaware of assemblies, so it won’t get garbage collected. The only way to get rid of assemblies in 1.0 and 1.1 is to unload the app domain in which it resides.

And therein lies the problem Dr Watson.

Running from the compiler in Visual Studio 2015 and using the Diagnostic Tools Window shows the following results after about 38 seconds. Note the Process memory is steadily climbing and the Garbage Collector (GC) keeps running but can't collect anything.

Diagnostic Tools Window

\$\endgroup\$
2
\$\begingroup\$

SMBF, 5 bytes

Although the brainfuck solution also works in SMBF, I decided to create a solution that only works in SMBF.

<[>+]

Since the source is placed on the tape to the left of the pointer, < will move the pointer to point at ], and then we loop, traveling forever on the tape.

\$\endgroup\$
1
\$\begingroup\$

Pushy, 3 bytes

1$a

Just keeps pushing to the stack...

1     % Push 1
$     % While last item != 0 (forever):
a     %   Push char-codes of the lowercase alphabet

This is just one example: several 3 byte solutions exist, such as 1$1, 1$&, 9$9, etc - anything that will "infinitely" push to the stack.

\$\endgroup\$
1
\$\begingroup\$

tinylisp repl, 12 bytes

(d f(q(L(f L

Defines a function f that will keep allocating memory when called. If submissions must be full programs, here's a 15-byte solution:

((v(d f(q(L(f L

Explanation

The repl supplies missing parens at the end of the line, so the code is really (d f(q(L(f L)))).

(d f(q(...))) defines f to be the unevaluated list (...). In tinylisp, functions are simply two-element lists. The first element is the parameter list and the second is the function body. Here, the first element is L, which (because it's not wrapped in parentheses) makes this a variadic function in which the entire argument list is assigned to L. The function body (f L) simply calls f again with L as its argument.

This is tail recursion, so the call stack doesn't come into play. But notice what happens to L on successive calls:

(f)        Called with no arguments; L gets empty list ()
(f ())     Called with one argument, empty list; L gets (())
(f (()))   Called with one argument, (()); L gets ((()))

And so on, wrapping the argument in another layer of list each time.

\$\endgroup\$
1
\$\begingroup\$

Fission, 3 bytes

RX+

Continuously creates atoms and increments its mass.

Try it online!

R                 creates an atom moving right
 X                clones atom, one keeps moving to the right, the other gets reflected left
  +               increment the atom's mass

Because of wrapping, this program will continuously create atoms with non-negative mass

Another alternative:

RX'

R and X works like you expect it to, and ' sets the atom's mass to the ASCII value of the next character it hits, ie 'R' (because of wrapping). Thus, this continuously creates atoms with the ASCII value of 'R'.

\$\endgroup\$
1
\$\begingroup\$

Java, 127+19=146

Golfed:

import java.util.*;class A{public static void main(String[]q){List l=new LinkedList();for(;;){String s="";for(int i=0;i>-1;++i)s+=' ';l.add(s);}}}

Ungolfed:

import java.util.*;

public class A {
  public static void main(String[] args) {
    List<String> l = new LinkedList<>();
    for (;;) {
      String s = new String();
      for (int i = 0; i > -1; ++i) {
        s += ' ';
      }
      l.add(s);
    }
  }
}

This program does not rely on the garbage collector or finalize() method like the other Java answers do. Java only interns and merges strings that are constructed from literals, unless specifically interned. That means this program will end up creating strings of size 231 essentially forever, assuming LinkedList works as expected.

\$\endgroup\$
3
  • \$\begingroup\$ You must have missed by answer based on explicitly interning Strings. Also, you can put just l.add(l) in the for loop to save a lot of bytes, and create the loop in the for initializer to get down to 103 bytes. \$\endgroup\$ Commented Dec 2, 2016 at 23:04
  • \$\begingroup\$ @DepressedDaniel I must have missed your answer. I saw several Java answers but they were all focused on the garbage collector. And you are right - by using raw types I can make this more efficient. I'll take a look later. Thanks for the tips. \$\endgroup\$
    – user18932
    Commented Dec 3, 2016 at 0:06
  • \$\begingroup\$ You can replace s+=' ';l.add(s); with l.add(s+=' '); \$\endgroup\$
    – Cyoce
    Commented Mar 16, 2017 at 20:21
1
\$\begingroup\$

PowerShell, 14 bytes

for(){$i+="z"}

Infinite loop creates a variable(string) and appends new characters to the end. Unbearably slow, took over an hour to consume two megabytes. Verified it would consume all the RAM available using something a bit faster: for(){$i+=("z"*9MB)}

\$\endgroup\$
1
  • \$\begingroup\$ Since .NET strings are just char[] in the background, you could use an array and do for(){$i+=,1} to save a byte. \$\endgroup\$ Commented Dec 5, 2016 at 19:16
1
\$\begingroup\$

Dyalog APL, 4 bytes

⊂⍣≡⍬

enclose

until

identical to the previous iteration (i.e. never, as each iteration has one more level of enclosure)

empty (numeric) list

The program starts as follows:

[], enclose that, yielding

[[]]. Is that identical to []? No, so we enclose that, yielding

[[[]]]. Is that identical to [[]]? No, so we enclose that...

Since each enclosure needs a new pointer, memory usage will slowly increase until WORKSPACE FULL.

\$\endgroup\$
5
  • \$\begingroup\$ I've already learned Lisp and Prolog, I should learn APL now \$\endgroup\$
    – tbodt
    Commented Dec 8, 2016 at 16:38
  • \$\begingroup\$ @tbodt Can I help you get started? \$\endgroup\$
    – Adám
    Commented Dec 8, 2016 at 16:44
  • \$\begingroup\$ sure, got any nice links? \$\endgroup\$
    – tbodt
    Commented Dec 8, 2016 at 16:46
  • \$\begingroup\$ @tbodt First, get the full version of Dyalog APL, and while you wait for your license to arrive, have a look at the "Learn" tab of tryapl.org. The book Mastering Dyalog APL is a must. If you don't want to pay, you can just download the PDF for free. \$\endgroup\$
    – Adám
    Commented Dec 8, 2016 at 16:55
  • \$\begingroup\$ @tbodt Make sure to check out #onelinerwednesday and YouTube. Use Twitter, Facebook, or visit the forums or send me an email if you get stuck or have questions. \$\endgroup\$
    – Adám
    Commented Dec 8, 2016 at 17:10
1
\$\begingroup\$

SmileBASIC, 18 bytes

@L
A$=A$+@A
GOTO@L

Keeps creating strings consisting of @A@A@A.... It would be much faster to use PUSH to modify the original string, but that would use more characters.

\$\endgroup\$
3
  • \$\begingroup\$ The old versions of A$ probably get garbage-collected. This technically does continuously allocate memory but it would be more spectacular if it crashed eventually :) \$\endgroup\$
    – snail_
    Commented Feb 7, 2017 at 13:44
  • \$\begingroup\$ There's no way to avoid SB's garbage collector, it's way too reliable. \$\endgroup\$
    – 12Me21
    Commented Feb 7, 2017 at 13:45
  • \$\begingroup\$ You could PUSH an array until you get Out of memory but that would in fact be longer. \$\endgroup\$
    – snail_
    Commented Feb 7, 2017 at 13:46
1
\$\begingroup\$

√ å ı ¥ ® Ï Ø ¿ , 3 bytes

(1)

Explanation

(   › Start an infinite loop
 1  › Push 1 to the stack
  ) › End an infinite loop
\$\endgroup\$
1
\$\begingroup\$

OIL, 12 bytes

Here in annotated form (remove anything but numbers to run):

1 # copy
-1 # from line -1 (containing, by default, a 0)
6 # to line 6 (the first line after the last line) %
8 # increment
2 # line 2 (marked with %)
6 # goto (since the next line will now be 0, go to line 0)

Even though seemingly nothing changes (lines are 0 by default and are being set to 0), internally, there's a difference between an unallocated line and a line with an explicit 0 in it.

\$\endgroup\$
1
\$\begingroup\$

C, 10 bytes

f(x){f();}

The x is needed for memory to be used in addition to stack space. This will endlessly make calls to itself each time taking ~32bits to store x.

\$\endgroup\$
1
\$\begingroup\$

Aceto, 2 bytes

e>

Pushes e (2.71..) on the stack, and moves the IP back to the first cell.

There are of course many 2-byte solutions in Aceto, (any single character literal (1234567890ePR'), followed by a command that makes the thing infinite (I can think of <>O, but there might be more), but I chose e> because it looks a bit like a heart (<3 sadly doesn't work).

\$\endgroup\$
1
\$\begingroup\$

asm2bf - 15 bytes

@l
psh 1
jmp %l

Will push 1 until the interpreter/system runs out of memory.

\$\endgroup\$
1
\$\begingroup\$

Rust, 35 31 bytes

-4 bytes thanks to madlaina (into_raw -> leak)

||loop{Box::leak(Box::new(0));}

Try it online

Full program, 40 bytes

fn main(){loop{Box::leak(Box::new(0));}}

Try it online

Unlike the other Rust solution, this uses Box::leak to leak the boxed value, turning it into a &'static mut i32.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Box::leak instead of Box::into_raw saves several bytes \$\endgroup\$
    – madlaina
    Commented Aug 14, 2020 at 15:12
0
\$\begingroup\$

Kotlin, 27 bytes

var o=Any()
while(1>0)o={o}

Stacking functions returning functions.

54 bytes if no .kts: fun main(a:Array<String>){var o=Any();while(1>0)o={o}}

\$\endgroup\$
0
\$\begingroup\$

F#, 22 bytes

let rec f x=f(1::x);()

Call it in F# interactive passing an empty list: f []

The function recursively calls itself, adding elements to the list. The tuple at the end is there so that the type inference can determine that the function return type is unit.

\$\endgroup\$
3
  • \$\begingroup\$ Could this be golfed to let rec f x=1::f(x)? \$\endgroup\$ Commented Dec 15, 2016 at 10:52
  • \$\begingroup\$ @PeterTaylor your code results in StackOverflowException, which (if I understand correctly) is not a desired outcome for this challenge. Curiously, the version I posted seems to be tail-recursive optimized. \$\endgroup\$
    – pmbanka
    Commented Dec 15, 2016 at 12:18
  • \$\begingroup\$ As a side note - if StackOverflowException is a valid option, then it can be even shorter: let rec f()=1::f(). But I think it is way more fun to just watch the FSI process to eat more and more memory :) \$\endgroup\$
    – pmbanka
    Commented Dec 15, 2016 at 12:28
0
\$\begingroup\$

BotEngine, 2x3=6

ve<
>e^

Rough translation:

forever:
  enqueue 'e'
  enqueue 'e'
\$\endgroup\$
2
  • \$\begingroup\$ I don’t know what this language even is, but it looks 2D — wouldn’t >e< work (or >e if there’s wrapping?) \$\endgroup\$
    – lynn
    Commented Dec 8, 2016 at 15:22
  • \$\begingroup\$ Unfortunately, no. I believe both would produce an error (missing argument on the e instruction), and the language doesn't have wrapping. \$\endgroup\$ Commented Dec 8, 2016 at 17:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.