Schreiben Sie ein Programm, das für immer ausgeführt wird und das mehr und mehr Speicher auf dem Heap reserviert, je länger es ausgeführt wird, zumindest bis Sie die Grenze des Betriebssystems für den verfügbaren Speicher erreichen.
Viele Kernel reservieren keinen Speicherplatz, den Sie zuweisen, bis Sie ihn für etwas verwenden. Wenn Ihr Programm also in C oder einer anderen einfachen Sprache ausgeführt wird, müssen Sie sicherstellen, dass Sie auf jeder Seite etwas schreiben. Wenn Sie eine interpretierte Sprache verwenden, müssen Sie sich darüber wahrscheinlich keine Gedanken machen.
Kürzester Code gewinnt.
(reduce conj [] (range))
(Clojure) erreicht bis zu 737 MB und hört dann einfach auf zu wachsen. Idk, wie es nicht ständig steigt. Es "denkt", dass ich die gesamte Liste am Ende ausdrucken möchte, damit nichts weggeworfen wird. Sehr frustrierend.Antworten:
Funge-98 (
cfunge
), 1 ByteIch hätte dies früher gepostet, habe mich aber dazu entschlossen, es zu testen, und es dauerte eine Weile, bis mein Computer wieder einsatzbereit war.
cfunge
speichert den Funge-Stack auf dem Heap des Betriebssystems (was leicht zu überprüfen ist, indem das Programm mit einer kleinen Speicherbegrenzung ausgeführt wird, was ich früher hätte tun sollen!), also einen unendlich wachsenden Stack (wie bei diesem Programm, das nur9
wiederholt ausgeführt wird); Funge-Programme, die standardmäßig vom Ende einer Zeile bis zum Anfang umgebrochen werden, weisen Speicherplatz für immer zu. Dieses Programm funktioniert wahrscheinlich auch in einigen Befunge-93-Implementierungen.Interessanter:
Dies war meine erste Idee und ist eine unendliche Zuweisung, die sich nicht auf den Funge-Stapel stützt (obwohl sie auch den Funge-Stapel in die Luft sprengt). Zunächst legt der
"
Befehl eine Kopie des restlichen Programms im Stapel ab (es ist eine Zeichenfolge, und das Programm wird umgebrochen, sodass das schließende Anführungszeichen auch als offenes Anführungszeichen dient). DannN
spiegelt sich das wieder (es hat standardmäßig keine Bedeutung) und das Programm wird rückwärts ausgeführt. Das"
Programm wird erneut ausgeführt und schiebt das Programm auf den Stapel - umgekehrt, diesmal mit demN
oberen Rand des Stapels - , woraufhin das Programm einen Umlauf ausführt und eine Bibliothek mit einem 4 - Buchstaben - Namen lädt (4(
; dieNULL
Bibliothek ist Teil voncfunge
Standardbibliothek).NULL
Definiert alle Großbuchstaben, dieL
reflektiert werden sollen#
Überspringt das Laden der Bibliothek auf dem Rückweg, verschiebt den4
uns unbekannten Junk auf den Stack und wiederholt das gesamte Programm von Anfang an. Da das mehrfache Laden einer Bibliothek eine Auswirkung hat und die Befehlsliste der Bibliothek für jede Kopie der Bibliothek einmal gespeichert werden muss (dies wird durch die Semantik von Funge-98 impliziert), führt dies zu einem Speicherverlust über einen Nicht-Stapelspeicher (bei dem es sich um einen handelt) alternative Methode zum Definieren von "Heap" in Bezug auf die Sprache und nicht auf das Betriebssystem.quelle
0
; es ist möglich, dass die Funge-Implementierung oder das Betriebssystem einen Weg finden, dies zu optimieren, da der betreffende Speicher bereits mit Nullen gefüllt ist). Ich habe nur9
willkürlich ausgewählt.Brainfuck, 5 Bytes
Dies erfordert einen Interpreter, der die Länge des Bandes nicht begrenzt.
quelle
Bash + Coreutils, 5
oder
Rubin, 5
yes
produziert endlose Ausgabe. Durch dasyes
Einfügen von Backticks wird die Shell angewiesen, alle Ausgaben zu erfassen und diese Ausgabe dann als Befehl auszuführen. Bash reserviert weiterhin Speicher für diese unendliche Zeichenfolge, bis der Heap-Speicher voll ist. Natürlich würde die resultierende Ausgabe ein ungültiger Befehl sein, aber wir sollten keinen Speicher mehr haben, bevor dies geschieht.Vielen Dank an @ GB für den Hinweis, dass dies auch ein Polyglott in Rubin ist.
quelle
Python, 16 Bytes
Verschachtelt so lange,
a
bis ein Fehler auftritt:Die ersten paar Iterationen (als Tupel) sehen so aus:
und so weiter und so fort.
quelle
> <> (Fisch), 1 Byte
Probieren Sie es hier aus!
0
kann tatsächlich durch eine beliebige Hexadezimalzahl 1-f ersetzt werden.Erläuterung
0
in> <> erstellt einfach eine 1x1-Codebox, in der der Fisch schwimmen kann. Sie fügt0
dem Stapel ständig ein hinzu , schwimmt nach rechts, umläuft0
den Stapel und fügt ihn erneut dem Stapel hinzu. Dies wird für immer so weitergehen.quelle
.
(oder ein beliebiges Zeichen ohne Leerzeichen), um das0
in die Ausführungslinie zu verschieben.0000000...
als einzelnes Integer-Literal zu lesen , und die Zeichenfolge, die er aufbaut, nimmt immer mehr Speicherplatz in Anspruch. Ein Programm, das so funktioniert wie dieses, wärea
(drückt 10 unendlich).Java 101 Bytes
Aufrufen des Hauptprogramms in einer Endlosschleife nach dem Erstellen und Wegwerfen eines Objekts. Die Garbage Collection übernimmt das Lecken, indem für jedes gelöschte Objekt 2 Objekte erstellt werden
quelle
Perl, 12 Bytes
In Perl erzeugt der
x
Operator mit einer Zeichenfolge links und einer Zahl rechts eine wiederholte Zeichenfolge. Also"abc" x 3
bewertet zu"abcabcabc"
.Der
x=
Operator mutiert das linke Argument und ersetzt den Inhalt der Variablen auf der linken Seite mit dem Ergebnis, dass der Inhalt so oft wiederholt wird, wie es die rechte Seite angibt.Perl hat eine Reihe von einer Reihe von seltsam in Variablen gebaut genannt, von denen eines
$"
, dessen Anfangswert ist ein Leerzeichen.Der
redo
Bediener springt an den Anfang der Anlage{}
.Wenn der
x=
Operator das erste Mal ausgeführt wird, ändert er den Wert von$"
von" "
"bis"" "
, was 9 Leerzeichen entspricht.Wenn der
x=
Operator das zweite Mal ausgeführt wird, ändert er den Wert von$"
auf" "
, was 81 Leerzeichen entspricht.Das dritte Mal
$"
wird eine 729 Byte lange Zeichenfolge von Leerzeichen.Ich denke, Sie können sehen, wohin das führt :).
quelle
$_.=7
meine Schleife inne, aber mir wurde klar, wenn ich sie verwenden könntex=
, würde der Speicher viel schneller ausgehen und dann lief ich losperldoc perlvar
, um etwas Passendes auszuwählen.{$^O++;redo}
ist ein Byte kürzer, wenn^O
es sich um ein einzelneschr(15)
Byte handelt. Es wird zwar viel langsamer Speicher verschwenden - unter Windows sind 1000000000 Iterationen erforderlich, um ein Byte zu verschwenden. Funktioniert auf jedem Betriebssystem, dessen Name mit einem lateinischen Buchstaben beginnt.sed, 5 bytes
Golf gespielt
Verwendung (jede Eingabe ist ausreichend)
Erklärt
Bildschirmfoto
Probieren Sie es online!
quelle
Haskell,
2319 BytesGibt die Summe einer unendlichen Liste aus
quelle
sum
ist definiert alsfoldl (+) 0
, und was die Strenge Analyse zu stoppen, um zu treten, um den Thunk-Ausbruch zu verhindern? Haben Sie es mit Optimierungen kompiliert ausgeführt?sum
Ich werde nicht im Voraus wissen, dass die Liste unendlich ist und bisprint
zur Summe muss sie zuerst ausgewertet werden. Und ja, ich habe es mit Optimierungen zusammengestelltInteger
stelle sicher, dass die Zahlen aufgrund der Standardeinstellung unbegrenzt sind und die Erinnerung, die das aktuelle Bignum- Ergebnis beansprucht , in der Tat zunehmen würde.sum xs = foldl (+) 0 xs
in einem konstanten Stapel ausgeführt werden kann, wie es jede imperative Schleife tun würde.foldl' (+) 0 xs
sicherlich wird. Das einzige, was mit Sicherheit Speicherplatz zuweist, ist das Zwischenergebnis.C ++ (mit g ++ - Compiler),
272315 BytesVielen Dank an Neop, der mir geholfen hat, 4 Bytes zu entfernen
Diese Lösung führt zu keinem wirklichen Speicherverlust, da sie alles auf dem Stapel zuordnet und somit einen Stapelüberlauf verursacht. Es ist einfach unendlich rekursiv. Bei jeder Rekursion wird Speicher zugewiesen, bis der Stapel überläuft.
Alternative Lösung
Diese Lösung verliert tatsächlich Speicher.
Valgrind Ausgang
Dies ist der Valgrind-Ausgang, nachdem das Programm einige Sekunden nach Ablauf der Laufzeit beendet wurde. Sie können sehen, dass es sicherlich Speicherlecks gibt.
quelle
int
bis ich sah, dass es dir so gut geht!C++
nur der g ++ - Dialekt: C ++ verbietet das Aufrufen von main; C ++ erfordert eineint main...
Deklaration. Aber die Lösung ist immer noch ordentlich :-)main
.JAVA,
817978 BytesJAVA (HotSpot)
7170 BytesZum Zeitpunkt meiner Veröffentlichung kürzer als andere Java-Antworten (81, später 79 Byte):
Wie von @Olivier Grégoire vorgeschlagen, kann ein weiteres Byte gespeichert werden:
Das
x+=x.intern()
Inkrementieren als for-Schleife würde nichts nützen, da zum Beenden der for-Anweisung immer noch ein Semikolon erforderlich ist.Wie von @ETHproductions vorgeschlagen,
x+=x
funktioniert auch nur die Verwendung von :Was auch von @Olivier Grégoires Tipp profitieren kann:
Meine einzigen Bedenken dabei sind, dass die Zuweisung von Daten auf dem Heap nicht garantiert ist , da eine effiziente JVM leicht erkennen kann, dass sie
x
der lokalen Funktion niemals entgeht. Die Verwendung vonintern()
vermeidet dieses Problem, da internierte Zeichenfolgen letztendlich in einem statischen Feld gespeichert werden. Allerdings generiert HotSpot einenOutOfMemoryError
Code für diesen Code. Ich denke, das ist in Ordnung.Update: @Olivier Gregoire wies auch darauf hin, dass der
x+=x
Code ausgeführt werden kann,StringIndexOutOfBoundsException
anstattOOM
wenn viel Speicher verfügbar ist. Dies liegt daran, dass Java den 32-Bit-int
Typ verwendet, um Arrays zu indizieren (und Strings sind nur Arrays vonchar
). Dies hat keine Auswirkung auf diex+=x.intern()
Lösung, da der für letzteres erforderliche Speicher in der Länge der Zeichenfolge quadratisch ist und daher auf die Größenordnung von 2 ^ 62 zugewiesenen Bytes skaliert werden sollte.quelle
x+=x;
?x+=x.intern()
das letzte Semikolon der for-Schleifeintern
aber ich war ziemlich zufrieden mit Unsafe und stellte fest, dass ich aufgehört hatte zu suchen, haha. Ursprünglich gab diese Frage "Memory Leak" an, weshalb ich nicht einfach eine String Concat-Antwort gemacht habe.# Java (HotSpot), 71 bytes
. B. ). Auf diese Weise brauchen Sie sich keine Sorgen zu machen, dass die Lösung möglicherweise betrügt. implementierungsspezifische Programme sind nicht nur im Golfsport verbreitet, sondern auch in der gesamten Programmierwelt. Solange Sie sich dessen bewusst sind, was Sie tun, ist dies manchmal geeigneter als ein portables Programm für beispielsweise ein Einzelprogramm. off script.x+=x;
erschöpft nicht die ganze Erinnerung. Mit 64 GB bekomme ich einStringIndexOutOfBoundsException
, kein OOM. Mit.intern()
bekomme ich noch die OOM.Perl 6 , 13 Bytes
Erläuterung:
@ =
Speichern Sie das Ergebnis in einem unbenannten Arrayeager
mach die folgende Liste eifrig0 .. *
unendlicher Bereich beginnend bei Nullquelle
///, 7 Bytes
Ersetzen ständig
a
mitaa
, bis zum Überdruss.quelle
aad naauseum
ad nauseam
=>aad naauseaam
//a/
? Das scheint für immer `` (nichts) durch zu ersetzena
, ist sich aber nicht sicher, ob dies genau spezifiziert ist.Python 3, 16 Bytes
Dies liegt an der Tatsache, dass es in Python 3 keine Beschränkung für die Ganzzahlgröße gibt. Stattdessen können Ganzzahlen so viel Speicher belegen, wie das System verarbeiten kann (wenn etwas an meinem Verständnis davon nicht stimmt, korrigieren Sie mich).
quelle
Rust, 46 Bytes
Beachten Sie etwas Interessantes an diesem Rust-Programm, bei dem Heap-Zuordnungen verloren gehen, bis der Speicher voll ist?
Das ist richtig, kein unsicherer Block. Rust garantiert die Speichersicherheit in sicherem Code (kein Lesen von nicht initialisierten Daten, kein Lesen nach "free", "double free" usw.), aber Speicherverluste gelten als absolut sicher. Es gibt sogar eine explizite Funktion, mit der der Compiler die RAII-Bereinigung von Out-of-Scope-Variablen vergisst, die ich hier verwende.
quelle
TI-83 Hex Assembly, 7 Bytes
Erstellt Appvars auf unbestimmte Zeit, bis
ERR:MEMORY
sie vom Betriebssystem ausgelöst werden. Laufen Sie mitAsm(prgmM)
. Ich zähle jedes Paar hexadezimaler Ziffern als ein Byte.quelle
Python, 8 Bytes
Das OP hat die technische Funktionalität eines Programms zugelassen, das technisch nicht "für immer" ausgeführt wird, sondern mehr Arbeitsspeicher zuweist, als ein Computer möglicherweise handhaben könnte. Dies ist kein Googolplex (das wären
10**10**100
11 Bytes), aber naiv ist Log Base 2 der Zahldh 10 ^ 94 Bits, um es darzustellen. WolframAlpha nennt das 10 ^ 76 größer als das tiefe Netz (bedenken Sie, dass es im Universum etwa 10 ^ 80 Atome gibt ).
Warum fragst du 2 statt 9? Es macht keinen großen Unterschied (die Verwendung von 9 würde die Anzahl der Bits nur um den Faktor 1 erhöhen
log2(9) = 3.2
, was den Exponenten nicht einmal ändert). Andererseits läuft das Programm mit 2 aber viel schneller, da die Berechnung einfacher ist. Dies bedeutet, dass der Speicher sofort voll ist, im Gegensatz zur 9-Version, die aufgrund der erforderlichen Berechnungen etwas länger dauert. Nicht notwendig, aber schön, wenn Sie dies "testen" möchten (was ich getan habe).quelle
Gelee ,
32 Bytes-1 Byte dank Dennis (
W
wraps)Eine Verknüpfung (dh Funktion oder Methode), die auch als vollständiges Programm funktioniert und deren Eingabe rekursiv in eine Liste einschließt.
Die Eingabe beginnt mit Null, sodass der erste Durchgang die Liste erstellt.
[0]
Der zweite Durchgang macht dies.
[[0]]
Der dritte Durchgang macht dies
[[[0]]]
und so weiter.
Vorherige 3 Bytes, die viel schneller lecken:
Verkettet rekursiv alle nicht leeren zusammenhängenden Unterlisten seiner Eingabe mit seiner Eingabe.
[0]
->[0,[0]]
->[0,[0],[0],[[0]],[0,[0]]]
und so weiter ...quelle
‘ß
sollte das reichen.Wß
sollte aber trotzdem passen.Java 7, 106 Bytes
Weniger Golf
Die
finalize
Methode wird vom Garbage Collector für ein Objekt aufgerufen, wenn die Garbage Collection feststellt, dass keine weiteren Verweise auf das Objekt vorhanden sind. Ich habe diese Methode einfach neu definiert, um eine Endlosschleife zu erstellen, damit der Garbage Collector den Speicher nie freigibt. In dermain
Schleife erstelle ich neue Objekte, die niemals bereinigt werden, so dass letztendlich der gesamte verfügbare Speicher belegt wird.Java 7 (lustige Alternative), 216 Bytes
Weniger Golf
Dies ist ein Spaß mehr als alles andere. In dieser Antwort wird die
Unsafe
Sun-Bibliothek verwendet, bei der es sich um eine nicht dokumentierte interne API handelt. Möglicherweise müssen Sie Ihre Compilereinstellungen ändern, um eingeschränkte APIs zuzulassen.Unsafe.allocateMemory
Weist eine festgelegte Anzahl von Bytes zu (ohne Begrenzungsüberprüfung), die sich nicht auf dem Heap und nicht in der Garbage Collector-Verwaltung von Java befinden, sodass dieser Speicher so lange erhalten bleibt, bis Sie einen AufrufUnsafe.freeMemory
tätigen oder bis der JVM-Speicher voll ist.quelle
Haskell, 24 Bytes
Das Hauptproblem in Haskell ist es, die Faulheit zu besiegen.
main
muss einenIO
Typ haben, alsomain=f 9
würde es nicht funktionieren , einfach anzurufen . Mit wirdmain=pure(f 9)
der Typ vonf 9
auf einenIO
Typ angehoben. Verwendung von Konstrukten jedoch wiemain=pure 9
nicht alles tun, die9
zurückgegeben oder nirgends angezeigt , sondern einfach verworfen, so dass keine Notwendigkeit besteht, das Argument zu bewertenpure
, dahermain=pure(f 9)
verursacht keine Speicher als zugeteilt werdenf
nicht genannt. Um die Auswertung zu erzwingen,$!
existiert der Operator. Es wendet einfach eine Funktion auf ein Argument an, wertet das Argument jedoch zuerst aus. Durch die Verwendung vonmain=pure$!f 9
Auswertungen wirdf
also kontinuierlich mehr Speicher zugewiesen.quelle
f x=f x
auch mit, oder? (f x=f x
erzeugt eine Endlosschleife, ohne jedoch neuen Speicher zuzuweisen .f!x=x*f(x*x)
sollte es optimierungssicher machen.Gleichstrom, 7 Bytes
[ddx]
Drückt einen String mit "ddx" auf den Stack.dx
dupliziert es und führt es dann als Code aus (wobei eine Kopie auf dem Stapel verbleibt). Bei der Ausführung werden zwei Duplikate erstellt und eines ausgeführt, wobei jedes Mal eine weitere Kopie auf dem Stapel verbleibt.quelle
Haskell (mit ghc 8.0.1), 11 Bytes
Non-Tail-Rekursion.
main
ruft sich selbst an und dann wieder selbst.quelle
Stack space overflow: current size 33624 bytes.
33 KB im Gegensatz zu den 6 GB des Gesamtspeichers, die das Betriebssystem meldet, ziemlich niedrig erscheint.C (Linux), 23 Bytes
sbrk()
Schritte der Oberseite des Datensegmentes durch die gegebene Anzahl von Bytes, wodurch wirksam die Größe des Speichers zu dem Programm zugeordnet Erhöhung - zumindest in dem ausgewiesenenVIRT
Bereichtop
ausgegeben. Dies funktioniert nur unter Linux - die MacOS-Implementierung ist anscheinend eine Emulation, die nur die Zuweisung von bis zu 4 MB ermöglicht.Also eine etwas allgemeinere Antwort:
C 25 Bytes
Ich habe es auf dem macOS Activity Monitor gesehen. Es ging den ganzen Weg bis zu etwa 48 GB, dann erhielt der Prozess schließlich ein SIGKILL-Signal. FWIW mein MacBook Pro hat 16 GB. Der größte Teil des verwendeten Speichers wurde als komprimiert gemeldet.
Beachten Sie, dass für die Frage effektiv jede Zuordnung geschrieben werden muss, was hier nicht explizit geschieht. Es ist jedoch wichtig zu beachten, dass für jeden
malloc(9)
Aufruf nicht nur die 9 vom Benutzer angeforderten Bytes zugewiesen werden. Für jeden zugewiesenen Block gibt es einen Malloc-Header, der auch von irgendwo auf dem Heap zugewiesen wird, auf den diemalloc()
Interna notwendigerweise schreiben .quelle
malloc()
ed-Block immer noch seinen eigenen zugewiesenen realen Speicherplatz haben muss. Dies funktioniert unter MacOS und Ubuntu.main(){main(malloc(9));}
, aber um einen Stapelüberlauf zu vermeiden, ist eine Tail-Call-Optimierung erforderlich, und gcc scheint dies nicht zu wollenmain
...Perl, 4 Bytes
Führt sich selbst im aktuellen Interpreter aus. Nach Abschluss der Ausführung kehrt die Ausführung zum aufrufenden Skript zurück, für das ein Aufrufstapel erforderlich ist.
quelle
Schläger, 13 Bytes
Ich bin nicht ganz sicher, ob meine Antwort unter diese Frage fällt. Bitte lassen Sie mich wissen, ob ich diese Antwort entfernen soll.
quelle
l
als eine Funktion, die Non-Tailcall-Rekursion ausführt. Ich würde sagen, es zählt.JavaScript
2221171615 Bytes4 Bytes wurden gespeichert, indem die Liste in eine andere Liste wie in der @ Jonathan Allan's Jelly-Antwort eingeschlossen wurde.
1 Byte dank @ETHProductions eingespart
Alternative Lösung 15 Bytes (funktioniert nur mit richtigen Tail Calls)
quelle
f=_=>f();f()
? 12 Bytesa=0
. Die erste Iteration würde ergebena=[undefined]
Ruby, 11 Bytes
Hält drückt
9
auf$*
zunächst die ein Array ist die Befehlszeilenargumente zum Ruby - Prozess zu halten.quelle
05AB1E , 2 Bytes
Probieren Sie es online! Werde einfach
abcdefghijklmnopqrstuvwyxz
für die Ewigkeit weiter auf den Stapel schieben .Alle möglichen 2-Byte-Lösungen:
quelle
Python, 35 Bytes
a
wird nie veröffentlicht und wird nur größer, bis Sie ein treffenMemoryError
Sie können die Ausführung in Python Tutor anzeigen .
quelle
a+=a,
?TI-BASIC, 8
(alle 1-Byte-Token und zwei Zeilenumbrüche)
Dies führt zu einem kontinuierlichen Speicherverlust, da ein strukturierter Steuerungsfluss, wie er beispielsweise
While
durch ein erwartet wird, geschlossen wirdEnd
und etwas auf den Stapel schiebt (nicht den Betriebssystemstapel, einen separaten Stapel im Heapspeicher), um den Überblick zu behalten. Aber hier verlassen wirGoto
die Schleife (also wird noEnd
ausgeführt, um das Ding vom Stapel zu entfernen), dasWhile
wird erneut gesehen, das Ding wird erneut geschoben usw. Also schiebt es sie einfach so lange, bis Sie es bekommenERR:MEMORY
quelle