49
\$\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\$
  • 13
    \$\begingroup\$ Is a stack overflow a valid solution? Does the memory have to be leaked or just allocated? \$\endgroup\$ – Wheat Wizard Dec 1 '16 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 Dec 1 '16 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\$ – Carcigenicate Dec 2 '16 at 1:05
  • 14
    \$\begingroup\$ Note to self: Save code before testing. Introducing mem-leaks might crash IDE... \$\endgroup\$ – steenbergh Dec 2 '16 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\$ – BenGoldberg Dec 17 '16 at 18:30

67 Answers 67

46
\$\begingroup\$

Funge-98 (cfunge), 1 byte

9

I would have posted this earlier, but decided to test it, and it took a while to get my computer back to a usable state. cfunge stores the Funge stack on the operating system's heap (which is easily verifiable by running the program with a small memory limit, something that I should have done earlier!), so an infinitely growing stack (as with this program, which just pushes 9 repeatedly; Funge programs wrap from the end of a line back to the start by default) will allocate memory forever. This program likely also works in some Befunge-93 implementations.

More interesting:

"NULL #(4

This was my first idea, and is an infinite allocation that doesn't rely on the Funge stack (although it blows up the Funge stack too). To start with, the " command pushes a copy of the rest of the program to the stack (it's a string, and the program wraps round, so the close quote also serves as the open quote). Then the N reflects (it has no meaning by default), causing the program to run backwards. The " runs again, and pushes the program to the stack – the other way round this time, with the N at the top of the stack – then the program wraps around, loading a library with a 4-letter name (4(; the NULL library is part of cfunge's standard library). NULL defines all uppercase letters to do reflect, so the L reflects, the # skips the library load on the way back, the 4 pushes junk we don't care about to the stack and the whole program repeats from the start. Given that loading a library multiple times has an effect, and requires the library's command list to be stored once for each copy of the library (this is implied by Funge-98's semantics), it leaks memory via non-stack storage (which is an alternative method of defining "heap", relative to the language rather than the OS).

\$\endgroup\$
  • 2
    \$\begingroup\$ I'm just going to accept this... \$\endgroup\$ – tbodt Dec 1 '16 at 19:08
  • \$\begingroup\$ Is it necessary for the number to be 9? Would it also work if it was 5? \$\endgroup\$ – tbodt Dec 1 '16 at 19:09
  • \$\begingroup\$ Anything that pushes to the stack works (except possibly 0; it's possible that the Funge implementation or the OS could find a way to optimize that out, given that the memory in question is full of zeroes already). I just picked 9 arbitrarily. \$\endgroup\$ – user62131 Dec 1 '16 at 19:10
  • 22
    \$\begingroup\$ Unaccepting because I want my reputation to still be 666. \$\endgroup\$ – tbodt Dec 1 '16 at 19:18
  • 7
    \$\begingroup\$ @tbodt Not a real reason to not accept. If you'd like, I'll -1 your question. Then when you accept, you'll have 703 still (note you have 703 now, not 666). \$\endgroup\$ – NoOneIsHere Dec 1 '16 at 23:20
30
\$\begingroup\$

Brainfuck, 5 bytes

+[>+]

This requires an interpreter that has no limit on the length of the tape.

\$\endgroup\$
  • 2
    \$\begingroup\$ I'm pretty sure it's +[>+] or else it would simply stop at the first iteration. ;) \$\endgroup\$ – Pâris Douady Dec 1 '16 at 14:48
  • \$\begingroup\$ You are right, sorry for the typo. \$\endgroup\$ – vsz Dec 1 '16 at 14:55
  • 40
    \$\begingroup\$ One of the rare times where a brainfuck solution is competitive... \$\endgroup\$ – FlipTack Dec 1 '16 at 19:00
  • \$\begingroup\$ @Flp.Tkc But it still loses. Maybe it will win someday... \$\endgroup\$ – NoOneIsHere Dec 4 '16 at 17:18
  • 6
    \$\begingroup\$ @SeeOneRhino : It already won once, beating all golfing languages> codegolf.stackexchange.com/questions/8915/… \$\endgroup\$ – vsz Dec 4 '16 at 17:48
22
\$\begingroup\$

Bash + coreutils, 5

or

Ruby, 5

`yes`

yes produces endless output. Putting yes in backticks tells the shell to capture all output and then execute that output as a command. Bash will continue allocating memory for this unending string until the heap runs out. Of course the resulting output would end up being an invalid command, but we should run out of memory before that happens.

Thanks to @GB for pointing out this is a polyglot in ruby too.

\$\endgroup\$
  • 7
    \$\begingroup\$ I was about to write the same and call it a Ruby program. \$\endgroup\$ – G B Dec 2 '16 at 6:57
  • 1
    \$\begingroup\$ and perl, I think. \$\endgroup\$ – abligh Dec 3 '16 at 12:54
18
\$\begingroup\$

Python, 16 bytes

Keeps nesting a until an error is reached:

a=0
while 1:a=a,

The first few iterations (as tuples) look like this:

0
(0,)
((0,),)
(((0,),),)

and so on and so forth.

\$\endgroup\$
18
\$\begingroup\$

><> (Fish), 1 byte

0

Try it here!

0 can actually be substituted for any hexadecimal number 1-f.

Explanation

0 in ><> simply makes a 1x1 codebox for the fish to swim in. It constantly adds a 0 onto the stack, swims right, which loops backaround to 0, adding it to the stack again. This will go on forever.

\$\endgroup\$
  • 2
    \$\begingroup\$ Now I'm wondering how many other 2-dimensional languages this works in. Most of them are stack-based, after all. \$\endgroup\$ – user62131 Dec 1 '16 at 19:15
  • 1
    \$\begingroup\$ Almost works in Cubix, but it requires a leading . (or any non-whitespace char) to move the 0 into the line of execution. \$\endgroup\$ – ETHproductions Dec 1 '16 at 20:04
  • 1
    \$\begingroup\$ Works in Ouroboros, but not in the same way: The interpreter tries to read 0000000... as a single integer literal, and the string that it builds up is what keeps taking more memory. A program that works the way this one does would be a (pushes 10 infinitely). \$\endgroup\$ – DLosc Dec 2 '16 at 5:48
12
\$\begingroup\$

Java 101 bytes

class A{public void finalize(){new A();new A();}public static void main(String[]a){for(new A();;);}}

Catching main Program in a endless Loop after creating and throwing away a object. Garbage collection does the job of leaking by creating 2 objects for each deleted ones

\$\endgroup\$
  • \$\begingroup\$ well I feel a little silly for not going with the obvious now, haha. I'd venture to say this is more elegant than mine \$\endgroup\$ – Poke Dec 1 '16 at 14:11
  • 1
    \$\begingroup\$ yeah, your code remembered me to that fact with the finalize() @poke \$\endgroup\$ – masterX244 Dec 1 '16 at 14:12
  • \$\begingroup\$ I think you could make it shorter by replacing main with a static initializer \$\endgroup\$ – tbodt Dec 1 '16 at 19:26
  • \$\begingroup\$ only works up to java6 and i only got higher versions around \$\endgroup\$ – masterX244 Dec 1 '16 at 22:03
  • 2
    \$\begingroup\$ haha using the garbage collector to cause a leak! great idea :) \$\endgroup\$ – Mark K Cowan Dec 2 '16 at 12:54
12
\$\begingroup\$

Perl, 12 bytes

{$"x=9;redo}

In perl, the x operator, with a string on the left and a number on the right, produces a repeated string. So "abc" x 3 evaluates to "abcabcabc".

The x= operator mutates the left argument, replacing contents of the variable on its left with the result of repeating it's contents as many times as its right hand side indicates.

Perl has a number of a number of strangely named built in variables, one of which is $", whose initial value is a single space.

The redo operator jumps to the beginning of the enclosing {}.

The first time the x= operator is done, it changes the value of $" from " "" to " ", which is 9 spaces.

The second time the x= operator is done, it changes the value of $" to " ", which is 81 spaces.

The third time, $" becomes a 729 byte long string of spaces.

I think you can see where this is going :).

\$\endgroup\$
  • \$\begingroup\$ You beat me to it! And yours is three bytes shorter. \$\endgroup\$ – Gabriel Benamy Dec 1 '16 at 3:10
  • 1
    \$\begingroup\$ It was just a matter of searching this web site for the smallest loop :). Also, I'd initially has $_.=7 in my loop, but realized if I could use x= it would run out of memory much much faster, and then ran perldoc perlvar to pick something suitable. \$\endgroup\$ – BenGoldberg Dec 1 '16 at 3:11
  • \$\begingroup\$ {$^O++;redo} is one byte shorter when ^O is a single chr(15) byte. Though it will waste memory at MUCH slower rate - 1000000000 iterations are required on Windows to waste one byte. Will work on any OS that have its name starting in Latin letter. \$\endgroup\$ – Oleg V. Volkov Dec 5 '16 at 14:05
11
\$\begingroup\$

sed, 5 bytes

Golfed

H;G;D

Usage (any input will do)

sed 'H;G;D' <<<""

Explained

#Append a newline to the contents of the hold space, 
#and then append the contents of the pattern space to that of the hold space.
H

#Append a newline to the contents of the pattern space, 
#and then append the contents of the hold space to that of the pattern space. 
G

#Delete text in the pattern space up to the first newline, 
#and restart cycle with the resultant pattern space.
D

Screenshot

enter image description here

Try It Online !

\$\endgroup\$
  • 2
    \$\begingroup\$ Strictly speaking this is GNU sed (semicolon is not standard sed) but a newline would work just as well as the semicolon anyway. \$\endgroup\$ – R.. Dec 4 '16 at 1:20
10
\$\begingroup\$

Haskell, 23 19 bytes

main=print$sum[0..]

Print the sum of an infinite list

\$\endgroup\$
  • \$\begingroup\$ This is a nice way to enforce evaluation, and it's very compact too. +1 \$\endgroup\$ – Esolanging Fruit Dec 2 '16 at 3:45
  • \$\begingroup\$ a compiler could very well run this in O(1) memory. In GHC, sum is defined as foldl (+) 0, and what's to stop the strictness analysis to kick in, to prevent the thunk blow-out? Did you run it compiled with optimizations? \$\endgroup\$ – Will Ness Dec 4 '16 at 9:51
  • \$\begingroup\$ @WillNess What could the answer be? sum won't know in advance that the list is infinite and to print the sum it must be evaluated first. And yes, I compiled it with optimizations \$\endgroup\$ – Angs Dec 4 '16 at 11:27
  • \$\begingroup\$ there wouldn't be an answer; but the calculation would run in O(1) space. Oops, strike that, because of the defaulting to Integer, the numbers are unbounded and the memory taken by the bignum current result, would indeed grow. \$\endgroup\$ – Will Ness Dec 4 '16 at 13:55
  • 1
    \$\begingroup\$ just to clarify, what I meant was that the calculation of sum xs = foldl (+) 0 xs can run in constant stack, as any imperative loop would. foldl' (+) 0 xs certainly will. So the only thing allocating memory for certain, is the bignum interim result. \$\endgroup\$ – Will Ness Dec 5 '16 at 10:47
9
\$\begingroup\$

C++ (using g++ compiler), 27 23 15 bytes

Thanks to Neop for helping me to remove 4 bytes

This solution does not really leak any memory because it allocates everything on the stack and thus causes a stack overflow. It is simply infinitely recursive. Each recursion causes some memory to be allocated until the stack overflows.

main(){main();}

Alternative solution

This solution actually leaks memory.

main(){for(;;new int);}

Valgrind output

This is the Valgrind output after terminating the program several seconds into the run time. You can see that it is certainly leaking memory.

==2582== LEAK SUMMARY:
==2582==    definitely lost: 15,104,008 bytes in 3,776,002 blocks
==2582==    indirectly lost: 0 bytes in 0 blocks
==2582==      possibly lost: 16 bytes in 4 blocks
==2582==    still reachable: 4 bytes in 1 blocks
==2582==         suppressed: 0 bytes in 0 blocks
\$\endgroup\$
  • 3
    \$\begingroup\$ The title is misleading; the question says to "write a program which runs forever and continuously allocates memory." \$\endgroup\$ – NobodyNada - Reinstate Monica Dec 1 '16 at 2:57
  • \$\begingroup\$ Oh I did not realize you already submitted an answer when I sent mine. \$\endgroup\$ – Neop Dec 1 '16 at 3:06
  • 1
    \$\begingroup\$ @Neop Well I didn't know you could ommit the int until I saw your's so thanks! \$\endgroup\$ – Wheat Wizard Dec 1 '16 at 3:08
  • 2
    \$\begingroup\$ Not C++, just the g++ dialect of it: C++ forbids calling main; C++ requires int main... declaration. But the solution is still neat :-) \$\endgroup\$ – Martin Ba Dec 1 '16 at 22:21
  • 1
    \$\begingroup\$ Indeed, C++ forbids calling main. \$\endgroup\$ – R.. Dec 4 '16 at 1:21
9
\$\begingroup\$

JAVA, 81 79 78 bytes

JAVA (HotSpot) 71 70 bytes

Shorter than other Java answers at the time I posted (81, later 79 bytes):

class A{public static void main(String[]a){String x="1";for(;;)x+=x.intern();}}

As suggested by @Olivier Grégoire, a further byte can be saved:

class A{public static void main(String[]a){for(String x="1";;)x+=x.intern();}}

Placing x+=x.intern() as the for loop increment would not help anything, because a semicolon is still required to end the for statement.

As suggested by @ETHproductions, just using x+=x works too:

class A{public static void main(String[]a){String x="1";for(;;)x+=x;}}

Which can also benefit from @Olivier Grégoire's tip:

class A{public static void main(String[]a){for(String x="1";;)x+=x;}}

My only misgivings about that is that it is not guaranteed to allocate data on the heap, as an efficient JVM can easily realize that x never escapes the local function. Using intern() avoids this concern because interned strings ultimately end up stored in a static field. However, HotSpot does generate an OutOfMemoryError for that code, so I guess it's alright.

Update: @Olivier Gregoire also pointed out that the x+=x code can run into StringIndexOutOfBoundsException rather than OOM when a lot of memory is available. This is because Java uses the 32-bit int type to index arrays (and Strings are just arrays of char). This doesn't affect the x+=x.intern() solution as the memory required for the latter is quadratic in the length of the string, and should thus scale up to on the order of 2^62 allocated bytes.

\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! I don't know Java very well; what would happen if you just did x+=x;? \$\endgroup\$ – ETHproductions Dec 2 '16 at 4:07
  • \$\begingroup\$ you can shave a semicolon off by putting the x+=x.intern() behind the last semicolon of the for loop \$\endgroup\$ – masterX244 Dec 2 '16 at 9:42
  • \$\begingroup\$ Nice answer. I knew there had to be something with string interning but I was pretty happy with Unsafe and finalize that I stopped looking, haha. Originally this question specified "memory leak" which is why I didn't just do a string concat answer. \$\endgroup\$ – Poke Dec 2 '16 at 14:09
  • \$\begingroup\$ If your answer depends on a specific implementation of Java, and wouldn't necessarily be portable to all Java implementations, you can place the information in the title (e.g. # Java (HotSpot), 71 bytes). That way, you don't need to worry about the solution potentially cheating; implementation-specific programs are common not just in golfing, but in the wider world of programming too, and as long as you're aware of what you're doing may sometimes be more appropriate than a portable program for, say, a one-off script. \$\endgroup\$ – user62131 Dec 2 '16 at 16:30
  • 1
    \$\begingroup\$ humm... x+=x; doesn't exhaust the whole memory. With 64 GB, I get an StringIndexOutOfBoundsException, not an OOM. With .intern() I still get the OOM. \$\endgroup\$ – Olivier Grégoire Dec 2 '16 at 18:30
8
\$\begingroup\$

Perl 6, 13 bytes

@= eager 0..*

Explanation:

@ = store the result into an unnamed array

eager make the following list eager

0 .. * infinite range starting at zero

\$\endgroup\$
8
\$\begingroup\$

///, 7 bytes

/a/aa/a

Constantly replace a with aa, ad nauseum.

\$\endgroup\$
  • 12
    \$\begingroup\$ *aad naauseum \$\endgroup\$ – timothymh Dec 2 '16 at 6:32
  • 1
    \$\begingroup\$ * ad nauseam => aad naauseaam \$\endgroup\$ – Aaron Dec 2 '16 at 12:30
  • \$\begingroup\$ What about //a/? That seems to forever replace `` (nothing) by a, but not sure if this is exactly specified. \$\endgroup\$ – Cedric Reichenbach Dec 2 '16 at 12:40
6
\$\begingroup\$

Python 3, 16 bytes

i=9
while 1:i*=i

This comes from the fact that there is no limit to integer size in Python 3; instead, integers can take up as much memory as the system can handle (if something about my understanding of this is wrong, do correct me).

\$\endgroup\$
  • \$\begingroup\$ The title implies that the memory should be leaked. But this doesn't actually leak memory. The author should probably clarify. \$\endgroup\$ – Wheat Wizard Dec 1 '16 at 3:50
6
\$\begingroup\$

Rust, 46 bytes

fn main(){loop{std::mem::forget(Box::new(1))}}

Notice something interesting about this Rust program, leaking heap allocations until out of memory?

That's right, no unsafe block. Rust guarantees memory safety in safe code (no reading of uninitialized data, read after free, double free etc.), but memory leaks are considered perfectly safe. There's even an explicit function to make the compiler forget about RAII cleanup of out of scope variables, which I use here.

\$\endgroup\$
6
\$\begingroup\$

TI-83 Hex Assembly, 7 bytes

PROGRAM:M
:AsmPrgm
:EF6A4E
:C3959D
:C9

Creates appvars indefinitely until an ERR:MEMORY is thrown by the OS. Run with Asm(prgmM). I count each pair of hex digits as one byte.

\$\endgroup\$
6
\$\begingroup\$

Python, 8 bytes

2**9**99

The OP has allowed the technicality of a program that doesn't technically run "forever", but allocates more memory than any computer could possibly handle. This isn't quite a googolplex (that would be 10**10**100, 11 bytes), but naively, log base 2 of the number is

>>> 9**99.
2.9512665430652752e+94

i.e., 10^94 bits to represent it. WolframAlpha puts that as 10^76 larger than the deep web (keep in mind that there are about 10^80 atoms in the universe).

Why 2 instead of 9 you ask? It doesn't make much of a difference (using 9 would only increase the number of bits by a factor of log2(9) = 3.2, which doesn't even change the exponent). But on the other hand, the program runs much faster with 2, since the calculation is simpler. This means it fills up memory immediately, as opposed to the 9 version, which takes a little longer due to the calculations required. Not necessary, but nice if you want to "test" this (which I did do).

\$\endgroup\$
5
\$\begingroup\$

Jelly, 3 2 bytes

-1 byte thanks to Dennis (W wraps)

A link (i.e. function or method), which also works as a full program, that recursively wraps its input into a list.

The input starts as zero so the first pass creates the list [0]
The second pass then makes this [[0]]
The third pass then makes this [[[0]]]
and so on...


Previous 3 byter, which leaks much faster:

;Ẇß

recursively concatenates all non-empty contiguous sublists of its input to its input.
[0] -> [0,[0]] -> [0,[0],[0],[[0]],[0,[0]]] and so on...

\$\endgroup\$
  • \$\begingroup\$ If I understand the rules correctly, ‘ß should be plenty. \$\endgroup\$ – Dennis Dec 1 '16 at 3:45
  • \$\begingroup\$ Does that really "continuously allocate memory" (thinking about Python keeping constant allocation for small ints). \$\endgroup\$ – Jonathan Allan Dec 1 '16 at 3:50
  • 1
    \$\begingroup\$ Fair enough. should still fit the bill though. \$\endgroup\$ – Dennis Dec 1 '16 at 3:52
5
\$\begingroup\$

Java 7, 106 bytes

class A{public void finalize(){for(;;)Thread.yield();}public static void main(String[]a){for(;;)new A();}}

Less Golfed

class A{
    @Override
    public void finalize(){
        for(;;) {
            Thread.yield();
        }
    }
    public static void main(String[]a){
        for(;;){
            new A();
        }
    }
}

The finalize method is called on an object by the garbage collector when garbage collection determines that there are no more references to the object. I have simply redefined this method to loop forever so the garbage collector never actually frees the memory. In the main loop I create new objects which will never be cleaned up so eventually this will use up all the available memory.

Java 7 (fun alternative), 216 bytes

import sun.misc.*;class A{public static void main(String[]a)throws Exception{java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(1>0);for(;;)((Unsafe)f.get(null)).allocateMemory(9);}}

Less Golfed

import sun.misc.*;
class A{
    public static void main(String[]a)throws Exception{
        java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe u = (Unsafe)f.get(null);
        for(;;) {
            u.allocateMemory(9);
        }
    }
}

This is a fun one more than anything else. This answer makes use of the Unsafe Sun library which is an undocumented internal API. You may need to change your compiler settings to allow restricted APIs. Unsafe.allocateMemory allocates a specified amount of bytes (without any boundary checking) which is not on the heap and not under java's garbage collector management so this memory will stick around until you call Unsafe.freeMemory or until the jvm runs out of memory.

\$\endgroup\$
  • 1
    \$\begingroup\$ Was wondering if I'd see Java here. \$\endgroup\$ – Magic Octopus Urn Dec 1 '16 at 14:59
  • \$\begingroup\$ Doesn't the first one only work if the garbage collector is running in a separate thread? \$\endgroup\$ – tbodt Dec 1 '16 at 19:26
  • \$\begingroup\$ @tbodt yes but i don't believe this is ever not the case. Garbage collection happens in a daemon thread called garbage collector \$\endgroup\$ – Poke Dec 1 '16 at 20:04
  • \$\begingroup\$ @Poke is that guaranteed? if not the answer is still fine, but you should clarify that it only works if the garbage collector runs in its own thread \$\endgroup\$ – tbodt Dec 1 '16 at 20:05
  • \$\begingroup\$ @tbodt I think so but I'm not certain, honestly. \$\endgroup\$ – Poke Dec 1 '16 at 20:16
5
\$\begingroup\$

Haskell, 24 bytes

f x=f$x*x
main=pure$!f 9

The main problem in Haskell is to beat the laziness. main needs to have some IO type, so simply calling main=f 9 would not work. Using main=pure(f 9) lifts the type of f 9 to an IO type. However using constructs like main=pure 9 does not do anything, the 9 is returned or displayed nowhere but simply discarded, so there is no need to evaluate the argument of pure, hence main=pure(f 9) does not cause any memory to be allocated as f is not called. To enforce evaluation, the $! operator exists. It simply applies a function to an argument but evaluates the argument first. So using main=pure$!f 9 evaluates f and hence continuously allocates more memory.

\$\endgroup\$
  • \$\begingroup\$ When compiled, the runtime detects the loop and breaks execution \$\endgroup\$ – Angs Dec 1 '16 at 9:41
  • \$\begingroup\$ @Angs I compiled with ghc on windows and it keeps happily allocating memory ... I stopped it at 3GB. \$\endgroup\$ – Laikoni Dec 1 '16 at 13:41
  • \$\begingroup\$ Using f x=f x works too, right? (−2 bytes) \$\endgroup\$ – wchargin Dec 3 '16 at 16:35
  • \$\begingroup\$ @wchargin I don't think so, f x=f x produces an infinite loop, but without allocating new memory. \$\endgroup\$ – Laikoni Dec 3 '16 at 17:58
  • \$\begingroup\$ Nice, causing the memory blow-out by the bignum calculations! f!x=x*f(x*x) should make it optimizations-proof. \$\endgroup\$ – Will Ness Dec 4 '16 at 13:58
5
\$\begingroup\$

dc, 7 bytes

[ddx]dx

[ddx] pushes a string containing "ddx" to the stack. dx duplicates it then executes it as code (leaving one copy on the stack). When executed, it makes two duplicates then executes one, leaving one more copy on the stack each time.

\$\endgroup\$
  • \$\begingroup\$ Wait, so this would exponentially allocate the memory if it could run in parallel? \$\endgroup\$ – HyperNeutrino Dec 2 '16 at 2:14
5
\$\begingroup\$

Haskell (using ghc 8.0.1), 11 bytes

m@main=m>>m

Non-tail recursion. main calls itself and then itself again.

\$\endgroup\$
  • \$\begingroup\$ Does this allocate on the heap or the stack? (I can believe either; it may well depend on the Haskell compiler in uses.) \$\endgroup\$ – user62131 Dec 1 '16 at 19:20
  • 1
    \$\begingroup\$ @ais523: it depends. Haskell has no call stack. The run time system RTS has a memory area for pattern matching which is also called "stack". This stack is allocated on the heap. Honestly, I don't know what's going on here, because the program fails with Stack space overflow: current size 33624 bytes. 33k seems quite low in contrast to the 6G of total memory that the OS is reporting. \$\endgroup\$ – nimi Dec 1 '16 at 20:56
  • 1
    \$\begingroup\$ @ais523: there seems to be a bug in the memory information of the ghc error message, so it's hard to tell what exactly happens. \$\endgroup\$ – nimi Dec 1 '16 at 23:26
  • \$\begingroup\$ Compiled on GHC 7.10.3 on Ubuntu, this seems takes a constant amount of memory even when optimizations are disabled \$\endgroup\$ – Angs Dec 2 '16 at 5:28
  • \$\begingroup\$ @Angs: hmm, I use ghc 8.0.1 on MacOS. I'll edit this in. \$\endgroup\$ – nimi Dec 2 '16 at 5:52
5
\$\begingroup\$

C (linux), 23 bytes

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

sbrk() increments the top of the data segment by the given number of bytes, thus effectively increasing the amount of memory allocated to the program - at least as reported in the VIRT field of top output. This only works on Linux - the macOS implementation is apparently an emulation that only allows allocation of up to 4MB.


So a slightly more general answer:

C, 25 bytes

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

I watched it on the macOS Activity Monitor. It went all the way up to about 48GB, then eventually the process received a SIGKILL signal. FWIW my macbook pro has 16GB. Most of the memory used was reported as compressed.

Note that the question effectively requires each allocation to be written to, which doesn't happen explicitly here. However it is important to note that for every malloc(9) call, it is not just the 9 user requested bytes that are allocated. For each block allocated there will be a malloc header that is also allocated from somewhere on the heap, which is necessarily written to by the malloc() internals.

\$\endgroup\$
  • \$\begingroup\$ With malloc, you are not directly writing in the memory since malloc does not initialise anything. The memory is only allocated because malloc needs some internal storage for memory managing. So the answer isn't really standard but I guess it works everywhere anyway. \$\endgroup\$ – Antzi Dec 2 '16 at 1:43
  • \$\begingroup\$ @Antzi Yes. However, I think this still works though because even though the user memory might not actually be allocated before it is written to, each malloc()ed block must still have its own real allocated space. This works on macOS and Ubuntu. \$\endgroup\$ – Digital Trauma Dec 2 '16 at 1:48
  • \$\begingroup\$ The condition in the question of each page being written to is rather meaningless; even if you want to assume an OS does not do proper commit accounting, regardless of implementation details there is necessarily a nonzero amount of bookkeeping needed per allocation. Whether it is adjacent to the allocation (causing pages to be touched) or not, it will eventually consume arbitrarily amounts of memory for bookkeeping with (necessarily) nonzero data. \$\endgroup\$ – R.. Dec 4 '16 at 1:26
  • \$\begingroup\$ You could get it one byte smaller as main(){main(malloc(9));}, but in order not to stack overflow, it needs tail call optimization, and gcc doesn't seem to want to do that on main... \$\endgroup\$ – R.. Dec 4 '16 at 1:34
  • \$\begingroup\$ If you replace malloc(9) with calloc(9,9) then there will be enough memory allocated for 9 instances of a 9-byte block (so between 81 and 144 bytes, depending on alignment. However, and more importantly, calloc() will zero-fill the block of memory, forcing the underlying OS to allocate storage to it. \$\endgroup\$ – CSM Dec 4 '16 at 13:13
5
\$\begingroup\$

Perl, 4 bytes

do$0

Executes itself, in the current interpreter. When finished, execution returns to the calling script, which requires a call stack.

\$\endgroup\$
  • \$\begingroup\$ Nice and short, though it doesn't waste memory quickly as mine. \$\endgroup\$ – BenGoldberg Dec 17 '16 at 18:22
4
\$\begingroup\$

Racket, 13 bytes

(let l()(l)1)

I'm not entirely certain if my answer falls under this question. Please let me know if I should remove this answer.

\$\endgroup\$
  • \$\begingroup\$ Can you explain how it works? \$\endgroup\$ – tbodt Dec 1 '16 at 17:46
  • 1
    \$\begingroup\$ oh, so it's defining l as a function that does non-tailcall recursion. i'd say it counts. \$\endgroup\$ – tbodt Dec 1 '16 at 19:23
  • \$\begingroup\$ @tbodt yes you're right on the money \$\endgroup\$ – Winny Dec 1 '16 at 21:54
4
\$\begingroup\$

JavaScript 22 21 17 16 15 Bytes

for(a=0;;)a=[a]

Saved 4 bytes by wrapping the list in another list as in @Jonathan Allan's Jelly answer.

Saved 1 byte thanks to @ETHProductions

Alternative solution 15 Bytes (only works with proper tail calls)

f=a=>f([a]);f()
\$\endgroup\$
  • 1
    \$\begingroup\$ On your 2nd example with ES6, couldn't you just do f=_=>f();f() ? 12 bytes \$\endgroup\$ – bitten Dec 1 '16 at 11:00
  • \$\begingroup\$ @bitten I am not sure. If it counts to blow the call stack, then that one without proper tail calls would be the way to go. With TCO, I don't think there would be any memory leaked, would there? \$\endgroup\$ – Lmis Dec 1 '16 at 11:09
  • \$\begingroup\$ both blow the call stack for me. i'm not really familiar with tail calls so i can't comment on that. \$\endgroup\$ – bitten Dec 1 '16 at 11:13
  • 1
    \$\begingroup\$ ah i see, i wasn't sure how yours was leaking memory \$\endgroup\$ – bitten Dec 1 '16 at 12:19
  • 1
    \$\begingroup\$ You could remove a=0. First iteration would result in a=[undefined] \$\endgroup\$ – Florent Dec 2 '16 at 15:47
4
\$\begingroup\$

Ruby, 11 bytes

loop{$*<<9}

Keeps pushing 9 onto $*, which is an array initially holding the command line arguments to the Ruby process.

\$\endgroup\$
4
\$\begingroup\$

05AB1E, 2 bytes

[A

Try it online! Will just keep pushing abcdefghijklmnopqrstuvwyxz onto the stack for eternity.

All possible 2-byte solutions:

[  # Infinite loop.
 A # Push alphabet.
 0 # Push 0.
 1 # Push 1.
 2 # Push 2.
 3 # Push 3.
 4 # Push 4.
 5 # Push 5.
 6 # Push 6.
 7 # Push 7.
 8 # Push 8.
 9 # Push 9.
 T # Push 10.
 X # Push 1.
 Y # Push 2.
 ® # Push -1.
 ¶ # Push \n.
 º # Push len(stack) > 0, so 0 once then 1 for eternity.
 ð # Push a space.
 õ # Push an empty string.
 ¾ # Push 0.
 ¯ # Push [].
 M # Push -inf.
 ) # Wrap current stack in an array.
\$\endgroup\$
  • \$\begingroup\$ Very thorough! Nice. \$\endgroup\$ – timothymh Dec 2 '16 at 6:34
3
\$\begingroup\$

Python, 35 bytes

def f(a=[]):a.append(a)
while 1:f()

a is never released and just gets bigger until you hit a MemoryError

You can view the execution on Python Tutor.

\$\endgroup\$
  • 1
    \$\begingroup\$ Can you do a+=a,? \$\endgroup\$ – Cyoce Dec 2 '16 at 1:23
  • \$\begingroup\$ No need for a function, here's my golf of it \$\endgroup\$ – FlipTack Dec 2 '16 at 7:25
  • \$\begingroup\$ @Flp.Tkc the question was changed after I wrote this answer I would have done what you did (+- couple of characters) if it was in its current format. \$\endgroup\$ – Noelkd Dec 2 '16 at 9:49
3
\$\begingroup\$

TI-BASIC, 8

:Lbl A
:While 1
:Goto A

(all 1-byte tokens, and two newlines)

This continuously leaks memory because structured control flow such as While anticipated being closed by an End and pushes something on the stack (not the OS stack, a separate stack in heap memory) to keep track of that. But here we're using Goto to leave the loop (so no End is executed to remove the thing from the stack), the While is seen again, the thing gets pushed again, etc. So it just keeps pushing them until you get ERR:MEMORY

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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