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
    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
    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\$ Dec 2, 2016 at 1:05
  • 15
    \$\begingroup\$ Note to self: Save code before testing. Introducing mem-leaks might crash IDE... \$\endgroup\$
    – steenbergh
    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\$ Dec 17, 2016 at 18:30

71 Answers 71

47
\$\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\$
8
  • 2
    \$\begingroup\$ I'm just going to accept this... \$\endgroup\$
    – tbodt
    Dec 1, 2016 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, 2016 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, 2016 at 19:10
  • 23
    \$\begingroup\$ Unaccepting because I want my reputation to still be 666. \$\endgroup\$
    – tbodt
    Dec 1, 2016 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\$ Dec 1, 2016 at 23:20
32
\$\begingroup\$

Brainfuck, 5 bytes

+[>+]

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

\$\endgroup\$
5
  • 2
    \$\begingroup\$ I'm pretty sure it's +[>+] or else it would simply stop at the first iteration. ;) \$\endgroup\$ Dec 1, 2016 at 14:48
  • \$\begingroup\$ You are right, sorry for the typo. \$\endgroup\$
    – vsz
    Dec 1, 2016 at 14:55
  • 40
    \$\begingroup\$ One of the rare times where a brainfuck solution is competitive... \$\endgroup\$
    – FlipTack
    Dec 1, 2016 at 19:00
  • \$\begingroup\$ @Flp.Tkc But it still loses. Maybe it will win someday... \$\endgroup\$ Dec 4, 2016 at 17:18
  • 6
    \$\begingroup\$ @SeeOneRhino : It already won once, beating all golfing languages> codegolf.stackexchange.com/questions/8915/… \$\endgroup\$
    – vsz
    Dec 4, 2016 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\$
2
  • 8
    \$\begingroup\$ I was about to write the same and call it a Ruby program. \$\endgroup\$
    – G B
    Dec 2, 2016 at 6:57
  • 1
    \$\begingroup\$ and perl, I think. \$\endgroup\$
    – abligh
    Dec 3, 2016 at 12:54
21
\$\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\$
3
  • 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, 2016 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\$ Dec 1, 2016 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, 2016 at 5:48
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\$
3
  • \$\begingroup\$ You beat me to it! And yours is three bytes shorter. \$\endgroup\$ Dec 1, 2016 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\$ Dec 1, 2016 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\$ Dec 5, 2016 at 14:05
11
\$\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\$
8
  • \$\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, 2016 at 14:11
  • 1
    \$\begingroup\$ yeah, your code remembered me to that fact with the finalize() @poke \$\endgroup\$
    – masterX244
    Dec 1, 2016 at 14:12
  • \$\begingroup\$ I think you could make it shorter by replacing main with a static initializer \$\endgroup\$
    – tbodt
    Dec 1, 2016 at 19:26
  • \$\begingroup\$ only works up to java6 and i only got higher versions around \$\endgroup\$
    – masterX244
    Dec 1, 2016 at 22:03
  • 2
    \$\begingroup\$ haha using the garbage collector to cause a leak! great idea :) \$\endgroup\$ Dec 2, 2016 at 12:54
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\$
1
  • 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\$ Dec 4, 2016 at 1:20
10
\$\begingroup\$

Haskell, 23 19 bytes

main=print$sum[0..]

Print the sum of an infinite list

\$\endgroup\$
7
  • \$\begingroup\$ This is a nice way to enforce evaluation, and it's very compact too. +1 \$\endgroup\$ Dec 2, 2016 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, 2016 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, 2016 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, 2016 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, 2016 at 10:47
9
\$\begingroup\$

///, 7 bytes

/a/aa/a

Constantly replace a with aa, ad nauseum.

\$\endgroup\$
3
  • 12
    \$\begingroup\$ *aad naauseum \$\endgroup\$
    – Tuesday
    Dec 2, 2016 at 6:32
  • 1
    \$\begingroup\$ * ad nauseam => aad naauseaam \$\endgroup\$
    – Aaron
    Dec 2, 2016 at 12:30
  • \$\begingroup\$ What about //a/? That seems to forever replace `` (nothing) by a, but not sure if this is exactly specified. \$\endgroup\$ Dec 2, 2016 at 12:40
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\$
7
  • 3
    \$\begingroup\$ The title is misleading; the question says to "write a program which runs forever and continuously allocates memory." \$\endgroup\$
    – NobodyNada
    Dec 1, 2016 at 2:57
  • \$\begingroup\$ Oh I did not realize you already submitted an answer when I sent mine. \$\endgroup\$
    – neop
    Dec 1, 2016 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, 2016 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, 2016 at 22:21
  • 1
    \$\begingroup\$ Indeed, C++ forbids calling main. \$\endgroup\$ Dec 4, 2016 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\$
13
  • \$\begingroup\$ Welcome to PPCG! I don't know Java very well; what would happen if you just did x+=x;? \$\endgroup\$ Dec 2, 2016 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, 2016 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, 2016 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, 2016 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\$ Dec 2, 2016 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\$

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\$
1
  • \$\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, 2016 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\$
0
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\$
3
  • \$\begingroup\$ If I understand the rules correctly, ‘ß should be plenty. \$\endgroup\$
    – Dennis
    Dec 1, 2016 at 3:45
  • \$\begingroup\$ Does that really "continuously allocate memory" (thinking about Python keeping constant allocation for small ints). \$\endgroup\$ Dec 1, 2016 at 3:50
  • 1
    \$\begingroup\$ Fair enough. should still fit the bill though. \$\endgroup\$
    – Dennis
    Dec 1, 2016 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\$
6
  • 1
    \$\begingroup\$ Was wondering if I'd see Java here. \$\endgroup\$ Dec 1, 2016 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, 2016 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, 2016 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, 2016 at 20:05
  • \$\begingroup\$ @tbodt I think so but I'm not certain, honestly. \$\endgroup\$
    – Poke
    Dec 1, 2016 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\$
5
  • \$\begingroup\$ When compiled, the runtime detects the loop and breaks execution \$\endgroup\$
    – Angs
    Dec 1, 2016 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, 2016 at 13:41
  • \$\begingroup\$ Using f x=f x works too, right? (−2 bytes) \$\endgroup\$
    – wchargin
    Dec 3, 2016 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, 2016 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, 2016 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\$
1
  • \$\begingroup\$ Wait, so this would exponentially allocate the memory if it could run in parallel? \$\endgroup\$
    – hyper-neutrino
    Dec 2, 2016 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\$
5
  • \$\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, 2016 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, 2016 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, 2016 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, 2016 at 5:28
  • \$\begingroup\$ @Angs: hmm, I use ghc 8.0.1 on MacOS. I'll edit this in. \$\endgroup\$
    – nimi
    Dec 2, 2016 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\$
5
  • \$\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, 2016 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\$ Dec 2, 2016 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\$ Dec 4, 2016 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\$ Dec 4, 2016 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, 2016 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\$
1
  • \$\begingroup\$ Nice and short, though it doesn't waste memory quickly as mine. \$\endgroup\$ Dec 17, 2016 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\$
3
  • \$\begingroup\$ Can you explain how it works? \$\endgroup\$
    – tbodt
    Dec 1, 2016 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, 2016 at 19:23
  • \$\begingroup\$ @tbodt yes you're right on the money \$\endgroup\$
    – Winny
    Dec 1, 2016 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\$
7
  • 1
    \$\begingroup\$ On your 2nd example with ES6, couldn't you just do f=_=>f();f() ? 12 bytes \$\endgroup\$
    – bitten
    Dec 1, 2016 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, 2016 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, 2016 at 11:13
  • 1
    \$\begingroup\$ ah i see, i wasn't sure how yours was leaking memory \$\endgroup\$
    – bitten
    Dec 1, 2016 at 12:19
  • 1
    \$\begingroup\$ You could remove a=0. First iteration would result in a=[undefined] \$\endgroup\$
    – Florent
    Dec 2, 2016 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\$
1
  • \$\begingroup\$ Very thorough! Nice. \$\endgroup\$
    – Tuesday
    Dec 2, 2016 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\$
3
  • 2
    \$\begingroup\$ Can you do a+=a,? \$\endgroup\$
    – Cyoce
    Dec 2, 2016 at 1:23
  • \$\begingroup\$ No need for a function, here's my golf of it \$\endgroup\$
    – FlipTack
    Dec 2, 2016 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, 2016 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\$
0

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.