Escriba un programa que se ejecute para siempre y asigne más y más memoria en el montón cuanto más tiempo se ejecute, al menos hasta que alcance el límite del sistema operativo en la cantidad de memoria que se puede asignar.
Muchos núcleos en realidad no reservarán la memoria que asigne hasta que la use para algo, por lo que si su programa está en C o en algún otro lenguaje de bajo nivel, deberá asegurarse de escribir algo en cada página. Si está utilizando un lenguaje interpretado, probablemente no tendrá que preocuparse por esto.
El código más corto gana.
(reduce conj [] (range))
(Clojure) llega a 737mb, luego deja de crecer. No sé cómo no está subiendo continuamente. "Piensa" que quiero imprimir la lista completa al final, por lo que no debería tirar nada. Muy frustrante.Respuestas:
Funge-98 (
cfunge
), 1 byteHubiera publicado esto antes, pero decidí probarlo y me llevó un tiempo volver a poner mi computadora en un estado utilizable.
cfunge
almacena la pila Funge en el montón del sistema operativo (que es fácilmente verificable ejecutando el programa con un pequeño límite de memoria, ¡algo que debería haber hecho antes!), por lo que una pila que crece infinitamente (como con este programa, que simplemente empuja9
repetidamente; Los programas de Funge (desde el final de una línea hasta el inicio de forma predeterminada) asignarán memoria para siempre. Es probable que este programa también funcione en algunas implementaciones de Befunge-93.Más interesante:
Esta fue mi primera idea, y es una asignación infinita que no depende de la pila Funge (aunque también explota la pila Funge). Para comenzar, el
"
comando empuja una copia del resto del programa a la pila (es una cadena, y el programa se ajusta, por lo que la comilla cerrada también sirve como comilla abierta). Luego, elN
reflejo (no tiene significado por defecto), lo que hace que el programa se ejecute al revés. Se"
ejecuta nuevamente y empuja el programa a la pila, al revés esta vez, con laN
parte superior de la pila, luego el programa se ajusta, cargando una biblioteca con un nombre de 4 letras (4(
; laNULL
biblioteca es parte decfunge
La biblioteca estándar).NULL
define todas las letras mayúsculas para reflejar, por lo queL
refleja, el#
omite la carga de la biblioteca en el camino de regreso,4
empuja basura que no nos importa a la pila y todo el programa se repite desde el principio. Dado que cargar una biblioteca varias veces tiene un efecto y requiere que la lista de comandos de la biblioteca se almacene una vez para cada copia de la biblioteca (esto está implícito en la semántica de Funge-98), pierde memoria a través del almacenamiento no apilado (que es un método alternativo para definir "montón", relativo al lenguaje en lugar del sistema operativo).fuente
0
; es posible que la implementación de Funge o el sistema operativo puedan encontrar una manera de optimizar eso, dado que la memoria en cuestión ya está llena de ceros). Acabo de elegir9
arbitrariamente.Brainfuck, 5 bytes
Esto requiere un intérprete que no tenga límite en la longitud de la cinta.
fuente
Bash + coreutils, 5
o
Rubí, 5
yes
produce salida sin fin. Poneryes
en backticks le dice al shell que capture toda la salida y luego ejecute esa salida como un comando. Bash continuará asignando memoria para esta cadena interminable hasta que se agote el montón. Por supuesto, el resultado resultante terminaría siendo un comando no válido, pero deberíamos quedarnos sin memoria antes de que eso suceda.Gracias a @GB por señalar que también es un políglota en rubí.
fuente
Python, 16 bytes
Sigue anidando
a
hasta que se alcanza un error:Las primeras iteraciones (como tuplas) se ven así:
y así sucesivamente y así sucesivamente.
fuente
> <> (Pez), 1 byte
Pruébalo aquí!
0
en realidad se puede sustituir por cualquier número hexadecimal 1-f.Explicación
0
in> <> simplemente crea una caja de códigos 1x1 para que los peces naden. Constantemente agrega una0
a la pila, nada hacia la derecha, lo que hace un bucle hacia atrás y la0
agrega nuevamente a la pila. Esto continuará por siempre.fuente
.
(o cualquier carácter que no sea un espacio en blanco) para moverlo0
a la línea de ejecución.0000000...
como un único entero literal, y la cadena que construye es lo que sigue teniendo más memoria. Un programa que funciona de la misma manera que este seríaa
(empuja 10 infinitamente).Java 101 bytes
Capturando el programa principal en un bucle sin fin después de crear y tirar un objeto. La recolección de basura hace el trabajo de fugas al crear 2 objetos por cada uno eliminado
fuente
Perl, 12 bytes
En perl, el
x
operador, con una cadena a la izquierda y un número a la derecha, produce una cadena repetida. Entonces"abc" x 3
evalúa a"abcabcabc"
.El
x=
operador muta el argumento izquierdo, reemplazando el contenido de la variable a su izquierda con el resultado de repetir su contenido tantas veces como lo indique su lado derecho.Perl tiene varias variables incorporadas con nombres extraños, una de las cuales es
$"
, cuyo valor inicial es un espacio único.El
redo
operador salta al comienzo del cerramiento{}
.La primera vez que el
x=
se realiza el operador, cambia el valor de$"
partir" "
"a" "
, que es de 9 espacios.La segunda vez que el
x=
operador termina, cambia el valor de$"
a" "
, que es 81 espacios.La tercera vez, se
$"
convierte en una cadena de espacios de 729 bytes de longitud.Creo que puedes ver por donde está yendo :).
fuente
$_.=7
en mi bucle, pero me di cuenta de que si podía usarlo,x=
se quedaría sin memoria mucho más rápido, y luego corríperldoc perlvar
para elegir algo adecuado.{$^O++;redo}
es un byte más corto cuando^O
es un solochr(15)
byte. Aunque desperdiciará memoria a una velocidad MUCHO más lenta, se requieren 1000000000 iteraciones en Windows para desperdiciar un byte. Funcionará en cualquier sistema operativo que tenga su nombre comenzando en letra latina.sed, 5 bytes
Golfed
Uso (cualquier entrada servirá)
Explicado
Captura de pantalla
¡Pruébelo en línea!
fuente
Haskell,
2319 bytesImprime la suma de una lista infinita
fuente
sum
se define comofoldl (+) 0
, y ¿qué es lo que detiene el análisis de rigurosidad para evitarlo? ¿Lo ejecutaste compilado con optimizaciones?sum
no sabrá de antemano que la lista es infinita y que, enprint
suma, debe evaluarse primero. Y sí, lo compilé con optimizacionesInteger
, los números son ilimitados y la memoria tomada por el resultado actual bignum , de hecho crecería.sum xs = foldl (+) 0 xs
puede ejecutarse en una pila constante, como lo haría cualquier ciclo imperativo .foldl' (+) 0 xs
Ciertamente lo hará. Entonces, lo único que asigna memoria con certeza es el resultado intermedio bignum.C ++ (usando el compilador g ++),
272315 bytesGracias a Neop por ayudarme a eliminar 4 bytes.
Esta solución realmente no pierde ninguna memoria porque asigna todo en la pila y por lo tanto causa un desbordamiento de la pila. Es simplemente infinitamente recursivo. Cada recursión hace que se asigne algo de memoria hasta que la pila se desborde.
Solución alternativa
Esta solución realmente pierde memoria.
Salida de Valgrind
Esta es la salida de Valgrind después de terminar el programa varios segundos después del tiempo de ejecución. Puedes ver que ciertamente está perdiendo memoria.
fuente
int
hasta que vi los tuyos, así que gracias!C++
, solo el dialecto de g ++: C ++ prohíbe llamar a main; C ++ requiereint main...
declaración. Pero la solución sigue siendo clara :-)main
.JAVA,
817978 bytesJAVA (HotSpot)
7170 bytesMás corto que otras respuestas de Java en el momento en que publiqué (81, más tarde 79 bytes):
Según lo sugerido por @Olivier Grégoire, se puede guardar un byte adicional:
Colocar
x+=x.intern()
como el incremento de bucle for no ayudaría en nada, porque todavía se necesita un punto y coma para finalizar la instrucción for.Según lo sugerido por @ETHproductions, solo usando
x+=x
trabajos también:Lo que también puede beneficiarse del consejo de @Olivier Grégoire:
Mis únicas dudas sobre eso es que no se garantiza que se asignen datos en el montón , ya que una JVM eficiente puede darse cuenta fácilmente de que
x
nunca escapa a la función local. El usointern()
evita esta preocupación porque las cadenas internadas finalmente terminan almacenadas en un campo estático. Sin embargo, HotSpot genera unOutOfMemoryError
código para ese código, así que supongo que está bien.Actualización: @Olivier Gregoire también señaló que el
x+=x
código puede ejecutarse enStringIndexOutOfBoundsException
lugar deOOM
cuando hay mucha memoria disponible. Esto se debe a que Java usa el tipo de 32 bitsint
para indexar matrices (y las cadenas son solo matrices dechar
). Esto no afecta a lax+=x.intern()
solución ya que la memoria requerida para este último es cuadrática en la longitud de la cadena, y por lo tanto debería escalar hasta el orden de 2 ^ 62 bytes asignados.fuente
x+=x;
?x+=x.intern()
el último punto y coma del bucle forintern
, pero estaba bastante contento con Inseguro y concluí que dejé de buscar, jaja. Originalmente, esta pregunta especificaba "pérdida de memoria", razón por la cual no hice una respuesta de cadena concat.# Java (HotSpot), 71 bytes
). De esa manera, no necesita preocuparse por la solución que potencialmente hace trampa; los programas específicos de implementación son comunes no solo en el golf, sino también en el mundo más amplio de la programación, y siempre que sepa lo que está haciendo, a veces puede ser más apropiado que un programa portátil para, por ejemplo, fuera del guión.x+=x;
no agota toda la memoria. Con 64 GB, obtengo unStringIndexOutOfBoundsException
, no un OOM. Con.intern()
todavía me sale el OOM.Perl 6 , 13 bytes
Explicación:
@ =
almacenar el resultado en una matriz sin nombreeager
haga la siguiente lista ansiosa0 .. *
rango infinito a partir de cerofuente
///, 7 bytes
Reemplazar constantemente
a
conaa
náuseas.fuente
aad naauseum
ad nauseam
=>aad naauseaam
//a/
? Eso parece reemplazar para siempre `` (nada) pora
, pero no estoy seguro de si esto se especifica exactamente.Python 3, 16 bytes
Esto viene del hecho de que no hay límite para el tamaño entero en Python 3; en cambio, los enteros pueden ocupar tanta memoria como el sistema puede manejar (si algo sobre mi comprensión de esto está mal, corríjame).
fuente
Óxido, 46 bytes
¿Notó algo interesante sobre este programa Rust, que pierde las asignaciones del montón hasta que se queda sin memoria?
Así es, no hay bloque inseguro. Rust garantiza la seguridad de la memoria en un código seguro (sin lectura de datos no inicializados, lectura libre, doble libre, etc.), pero las pérdidas de memoria se consideran perfectamente seguras. Incluso hay una función explícita para hacer que el compilador se olvide de la limpieza de RAII de variables fuera de alcance, que uso aquí.
fuente
Conjunto hexagonal TI-83, 7 bytes
Crea appvars indefinidamente hasta que
ERR:MEMORY
el sistema operativo arroja uno. Corre conAsm(prgmM)
. Cuento cada par de dígitos hexadecimales como un byte.fuente
Python, 8 bytes
El OP ha permitido la tecnicidad de un programa que técnicamente no se ejecuta "para siempre", pero asigna más memoria de la que cualquier computadora podría manejar. Esto no es un googolplex (eso sería
10**10**100
, 11 bytes), pero ingenuamente, la base de registro 2 del número eses decir, 10 ^ 94 bits para representarlo. WolframAlpha dice que es 10 ^ 76 más grande que la red profunda (tenga en cuenta que hay alrededor de 10 ^ 80 átomos en el universo ).
¿Por qué 2 en lugar de 9 preguntas? No hace mucha diferencia (usar 9 solo aumentaría el número de bits por un factor de
log2(9) = 3.2
, que ni siquiera cambia el exponente). Pero, por otro lado, el programa se ejecuta mucho más rápido con 2, ya que el cálculo es más simple. Esto significa que llena la memoria inmediatamente, a diferencia de la versión 9, que lleva un poco más de tiempo debido a los cálculos requeridos. No es necesario, pero bueno si quieres "probar" esto (lo que hice).fuente
Jalea ,
32 bytes-1 byte gracias a Dennis (
W
wraps)Un enlace (es decir, función o método), que también funciona como un programa completo, que envuelve recursivamente su entrada en una lista.
La entrada comienza como cero, por lo que la primera pasada crea la lista.
[0]
La segunda pasada hace esto.
[[0]]
La tercera pasada hace esto
[[[0]]]
y así sucesivamente ...
3 byter anterior, que se filtra mucho más rápido:
concatena recursivamente todas las sublistas contiguas no vacías de su entrada a su entrada.
[0]
->[0,[0]]
->[0,[0],[0],[[0]],[0,[0]]]
y así sucesivamente ...fuente
‘ß
debería ser suficiente.Wß
Sin embargo, aún debe ajustarse a la factura.Java 7, 106 bytes
Menos golf
El
finalize
recolector de basura llama al método en un objeto cuando la recolección de basura determina que no hay más referencias al objeto. Simplemente he redefinido este método para hacer un bucle para siempre, por lo que el recolector de basura nunca libera la memoria. En elmain
bucle, creo nuevos objetos que nunca se limpiarán, por lo que eventualmente se usará toda la memoria disponible.Java 7 (alternativa divertida), 216 bytes
Menos golf
Esta es una diversión más que cualquier otra cosa. Esta respuesta hace uso de la
Unsafe
biblioteca Sun, que es una API interna no documentada. Es posible que deba cambiar la configuración del compilador para permitir API restringidas.Unsafe.allocateMemory
asigna una cantidad específica de bytes (sin ninguna verificación de límites) que no está en el montón y no está bajo la administración del recolector de basura de Java, por lo que esta memoria se mantendrá hasta que llameUnsafe.freeMemory
o hasta que jvm se quede sin memoria.fuente
Haskell, 24 bytes
El principal problema en Haskell es vencer a la pereza.
main
necesita tener algúnIO
tipo, por lo que simplemente llamarmain=f 9
no funcionaría. El usomain=pure(f 9)
eleva el tipo def 9
a unIO
tipo. Sin embargo, el uso de construcciones comomain=pure 9
no hace nada,9
se devuelve o se muestra en ninguna parte, sino que simplemente se descarta, por lo que no es necesario evaluar el argumento depure
, pormain=pure(f 9)
lo tanto , no causa que se asigne ninguna memoria comof
no se llama. Para hacer cumplir la evaluación, el$!
operador existe. Simplemente aplica una función a un argumento pero primero evalúa el argumento. Por lo tanto, el usomain=pure$!f 9
evalúaf
y, por lo tanto, asigna continuamente más memoria.fuente
f x=f x
obras también, ¿verdad? (−2 bytes)f x=f x
produce un bucle infinito, pero sin asignar memoria nueva.f!x=x*f(x*x)
debería hacerlo a prueba de optimizaciones.dc, 7 bytes
[ddx]
empuja una cadena que contiene "ddx" a la pila.dx
duplica y luego lo ejecuta como código (dejando una copia en la pila). Cuando se ejecuta, hace dos duplicados y luego ejecuta uno, dejando una copia más en la pila cada vez.fuente
Haskell (usando ghc 8.0.1), 11 bytes
Recursión sin cola.
main
se llama a sí mismo y luego a sí mismo nuevamente.fuente
Stack space overflow: current size 33624 bytes.
33k parece bastante bajo en contraste con los 6G de memoria total que informa el sistema operativo.C (Linux), 23 bytes
sbrk()
incrementa la parte superior del segmento de datos en el número dado de bytes, lo que aumenta efectivamente la cantidad de memoria asignada al programa, al menos como se informa en elVIRT
campo detop
salida. Esto solo funciona en Linux: la implementación de macOS es aparentemente una emulación que solo permite la asignación de hasta 4 MB.Entonces, una respuesta un poco más general:
C, 25 bytes
Lo vi en el Monitor de actividad de macOS. Llegó hasta aproximadamente 48 GB, luego, finalmente, el proceso recibió una señal SIGKILL. FWIW mi macbook pro tiene 16 GB. La mayor parte de la memoria utilizada se informó como comprimida.
Tenga en cuenta que la pregunta efectivamente requiere que se escriba cada asignación, lo que no sucede explícitamente aquí. Sin embargo, es importante tener en cuenta que para cada
malloc(9)
llamada, no solo se asignan los 9 bytes solicitados por el usuario. Para cada bloque asignado, habrá un encabezado malloc que también se asigna desde algún lugar del montón, que necesariamente es escrito por losmalloc()
internos.fuente
malloc()
bloque ed debe tener su propio espacio asignado real. Esto funciona en macOS y Ubuntu.main(){main(malloc(9));}
, pero para no apilar el desbordamiento, necesita una optimización de llamada de cola, y gcc no parece querer hacer eso elmain
...Perl, 4 bytes
Se ejecuta a sí mismo, en el intérprete actual. Cuando finaliza, la ejecución vuelve al script de llamada, que requiere una pila de llamadas.
fuente
Raqueta, 13 bytes
No estoy del todo seguro si mi respuesta corresponde a esta pregunta. Avíseme si debo eliminar esta respuesta.
fuente
l
como una función que hace una recursión sin cola. Yo diría que cuenta.JavaScript
2221171615 BytesAhorró 4 bytes envolviendo la lista en otra lista como en la respuesta de @Jonathan Allan's Jelly.
Guardado 1 byte gracias a @ETHProductions
Solución alternativa de 15 bytes (solo funciona con llamadas de cola adecuadas)
fuente
f=_=>f();f()
? 12 bytesa=0
. La primera iteración resultaría ena=[undefined]
Ruby, 11 bytes
Sigue empujando
9
sobre$*
, que es una matriz inicialmente que sostiene los argumentos de línea de comandos para el proceso de Ruby.fuente
05AB1E , 2 bytes
Pruébalo en línea! Seguirá empujando
abcdefghijklmnopqrstuvwyxz
en la pila por la eternidad.Todas las posibles soluciones de 2 bytes:
fuente
Python, 35 bytes
a
nunca se lanza y solo se hace más grande hasta que golpeas unMemoryError
Puede ver la ejecución en Python Tutor .
fuente
a+=a,
?TI-BASIC, 8
(todos los tokens de 1 byte y dos líneas nuevas)
Esto continuamente pierde memoria porque el flujo de control estructurado, como el
While
anticipado por un cierre,End
y empuja algo en la pila (no la pila del sistema operativo, una pila separada en la memoria del montón) para realizar un seguimiento de eso. Pero aquí estamos usandoGoto
para dejar el bucle (para que noEnd
se ejecute nada para eliminar la cosa de la pila),While
se vuelve a ver, la cosa se empuja de nuevo, etc. Así que sigue empujándolos hasta que se obtieneERR:MEMORY
fuente