Su tarea es crear una pérdida de memoria . Este es un programa que utiliza mucha memoria, hasta que la computadora se agota y tiene que hacer algunos cambios para evitar que se agote. La única forma de liberar la memoria es matando el programa en el administrador de tareas o usando una línea de comando kill como taskkill /im yourprogram /f
(en Windows) o incluso reiniciando la computadora. El simple hecho de cerrar la aplicación no debería evitar que continúe acaparando la memoria.
Reglas:
Las bombas de horquilla de cualquier tipo están prohibidas. ¡Eso significa que la infame línea Bash
:(){ :|:&};:
está prohibida!La aplicación debe ser de un solo subproceso. Esto implica la regla de la bomba tenedor.
El programa no debe ejecutar otros programas. Esto significa que no puedes hacer algo así
run(memoryfiller.exe)
. La única excepción a esto son los programas que se incluyen con su sistema operativo o idioma, que no están diseñados principalmente para consumir memoria (es decir, tienen otro propósito). Esto significa que cosas comocat
yln -s
están permitidas.Puede tomar tanta memoria como desee. Mientras más, mejor.
El código debe explicarse completamente.
Buena suerte. Este es un concurso de popularidad, por lo que gana el código con más votos después de 10 días desde la fecha de solicitud.
fuente
while(1)malloc(999);
?Respuestas:
Ventanas
La API Win32 le permite asignar memoria en otros procesos y luego leer / escribir esa memoria de forma remota. Este programa tiene solo un subproceso, que utiliza para enumerar cada proceso en ejecución en el sistema, y luego asigna repetidamente buffers de 1 MB en cada proceso hasta que la asignación falla. Cuando termina con un proceso, pasa al siguiente. Las asignaciones no se liberan cuando finaliza el programa de llamada, solo cuando / si finaliza cada proceso de destino. Esto cuelga una máquina virtual Windows 7 de 2GB en aproximadamente 10 segundos. Requiere correr como administrador.
Compilar:
cl /MD leak.cpp /link psapi.lib
fuente
Java
Explicación
Puede suponer que, dado que no hay referencias en el código (aparte de
count
lo que puede ignorar con seguridad), no puede filtrarse. Sin embargo, el finalizador crea dos nuevas Hydras, y aunque tampoco contiene referencias para estos, se quedarán hasta que finalicen. Esto significa que el programa solo pierde memoria durante la recolección de basura, de ahí las llamadas aSystem.gc()
ySystem.runFinalization()
.fuente
System.gc()
ySystem.runFinalization()
necesarios? Es decir, ¿gc se ejecutará aleatoriamente a veces, o tiene que llenar algo de memoria o llamar a gc?System.gc()
ySystem.runFinalization()
no sería necesario. La recolección de basura ocurriría naturalmente debido a la presión de la memoria. Sin embargo, en esta aplicación no hay presión de memoria hasta que la recolección de basura comienza a ejecutarse. Pensé en introducir artificialmente algunos (por ejemplo, moviéndomenew Hydra()
dentro del bucle), pero pensé que esto era más malvado.C
Usando el lenguaje de programación C y probado con el kernel de Linux 2.6.32-49-generic y libc-2.11.1.so.
Esto se logra bloqueando cualquier señal, excepto SIGKILL y SIGSTOP.
Esto realmente me confundió ... Matarlo o cerrarlo resulta en la finalización del proceso, lo que permite que el sistema operativo recupere cualquier memoria asignada por el proceso. Pero luego pensé que cerrándolo podría significar cerrar la terminal o cualquier otro proceso principal que ejecute el proceso de pérdida de memoria. Si acerté, resolví este problema bloqueando cualquier señal, lo que convierte el proceso en un demonio cuando el proceso padre finaliza. De esa manera, puede cerrar el terminal en el que se está ejecutando el proceso y continuará ejecutándose y se procederá a la pérdida de memoria.
El proceso no se bifurca.
No se generan nuevos hilos.
No se generan nuevos procesos.
Tanto como el sistema operativo puede proporcionar.
Comentarios agregados a la fuente.
Y finalmente aquí está el código:
Para cualquiera que esté interesado en lo que sucede si mantiene este programa en funcionamiento: en mi sistema de prueba con 2 GB de RAM y 4 GB de espacio de intercambio, tardé unos 10 minutos en llenar la RAM e intercambiar. El asesino de OOM comenzó su trabajo y tres minutos después todos los procesos han sido eliminados. Incluso el mouse, el teclado y la pantalla han sido eliminados por el sistema. /var/log/kern.log no muestra información útil, excepto los procesos que se han eliminado.
fuente
Pure Bash
No es una bomba tenedor, lo prometo:
Se parece mucho a una bomba tenedor, y utiliza una técnica recursiva similar, pero no tenedores. Por supuesto, esto ejecutará su shell sin memoria, por lo que se recomienda iniciar un nuevo shell antes de pegar este comando.
:
$@
(lista arg) duplicada:
función se llama con un argumento inicial:
Salida:
En una edición anterior de esta respuesta lo hice
a=$(yes)
, pero noté la regla "El programa no debe ejecutar otro programa", por lo que necesito usar puro en subash
lugar sin llamar a ningún coreutils ni a ninguna otra cosa.Aqui hay otro más:
POR FAVOR NO HAGA FUNCIONAR ESTO EN UNA MÁQUINA DE PRODUCCIÓN
Una vez más, esto no es una bomba tenedor: todo se ejecuta desde un hilo. Este parece bastante útil para poner de rodillas a mi Ubuntu VM, con poco espacio para la recuperación, aparte de reiniciar.
Como en la clásica bomba tenedor,
:()
se define una función recursiva . Sin embargo, no desvía las llamadas a sí mismo. En cambio, se llama a sí mismo con un argumento, que se llama a sí mismo en una sustitución de proceso . Debido a que la sustitución de procesos funciona al abrir un descriptor de archivo/dev/fd/n
, esto no solo consume memoria del proceso (bash), sino que también consumirá algo de memoria del núcleo. En mi máquina Ubuntu, esto tiene el efecto de hacer que el administrador de ventanas deje de funcionar después de unos segundos, luego, poco después de terminar con esta pantalla:Al hacer clic
OK
, aparece esta pantalla:Ninguna de estas opciones parece ser de gran ayuda; en este punto, reiniciar parece ser la única buena opción.
fuente
$ which yes
->/usr/bin/yes
XML
Luego, pase el documento a un analizador XML que no haga detección de bucle / recursión de referencia de entidad. Por ejemplo,
xpath
incluido con perl:Cómo funciona:
<boom a="&a;">
"&a;"
en"&b;&b;"
"&b;"
en"&c;&c;"
(en el retorno, se expandirá el otro"&b;"
)"&c;"
etc.Si pudiera ocurrir una expansión completa, habría una expansión de 2 ^ 52 de "ka-boom!". Suponiendo 2 bytes por carácter, intentará usar 64 PiB. La expansión va "ka-boom!" a la vez, por lo que generalmente puede verlo usar toda la memoria en la parte superior.
Esto tiene varios nombres, buena descripción aquí: http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion
fuente
C ++
¡Este código fue inesperado! Colgó mi computadora mientras el administrador de tareas estaba abierto y mostró que tomó 890 Mb de memoria en 1 segundo y luego también se colgó. No sé cómo funciona esto, tal vez sigue dando memoria a una variable. Para explorar más de este código, agregué una declaración
delete a;
y todo estuvo bien durante la prueba (sin bloqueo) Entonces, creo que la porción de memoria es dado (debido anew int
) y luego devuelto (debido adelete a
) al espacio libre en el nuevo código a continuación.Por lo tanto, concluyo que ¡ NO RAM EN ESTE MUNDO PUEDE MANEJAR ESTE CÓDIGO!
EDITAR : Pero muchos procesadores pueden, por ejemplo
intel core 2 duo
, no pueden manejar este código perointel core i-series
pueden (funcionó para mí ...)Recuerde que la respuesta a la pregunta es el primer código, el segundo es para explicación.
fuente
new int
dispositivo aunque sobrescribió el puntero, por lo que nunca podrá acceder a él nuevamente ... Así que no se llama a la recolección de basura y llena la memoria más rápido que un niño gordo come bolosBrainFuck
Explicación:
Para ingresar al bucle, aumenta la celda a 1. Se mueve a la siguiente celda aumentando eso a 1 siempre que la última celda sea positiva.
Por lo general, un intérprete BrainFuck tiene fallas al tener un límite estricto para el número de celdas en la cinta, pero algunos intérpretes agregan celdas dinámicamente. Estos continuarán consumiendo memoria hasta que ya no se consuma.
beef
es uno de esos intérpretes y está disponible en el Centro de software de Ubuntu y mi ejecución actual en una máquina no utilizada comenzó hace 29 horas y ha consumido 1 GB de RAM en ese momento. Aquí está la salida detop
Tiene 4 GB de caché y 6 GB de intercambio, así que supongo que actualizaré esta respuesta con cómo fue en unos 12 días.
ACTUALIZACIÓN 03.24 17:11
ACTUALIZACIÓN 03.31 00:20
Así que ha estado funcionando durante 10 días. Parece que se ejecutará durante al menos 10 más antes de que ocurra algo interesante.
fuente
C y POSIX
Aquí estoy apuntando a una solución altamente portátil. El problema es que C puro no parece tener una manera de decirle al sistema operativo que la memoria debe permanecer asignada después de que se cierra el programa. Entonces me permito usar POSIX; la mayoría de los sistemas operativos tienen cierta demanda de compatibilidad POSIX, incluidos Windows, Linux y MacOS X. Sin embargo, solo lo he probado en Ubuntu 12.04 de 32 bits. No requiere permisos de superusuario.
Esta solución es esencialmente la
while(1){malloc(1);}
solución tradicional . Sin embargo, en lugar de malloc, utiliza las funciones de memoria compartida POSIX. Dado que asigna un identificador de memoria compartida a cada asignación, aún es posible acceder a la memoria una vez que finaliza el proceso. Por lo tanto, el núcleo no puede liberar la memoria.fuente
C#
Olvidar darse de baja de los eventos antes de que el controlador salga del alcance hará que .NET pierda memoria hasta que arroje OutOfMemoryException.
Explicación : Dentro del
while
bucle, construimos un nuevo objeto, lo que hace que el marco asigne más memoria, pero también evitamos queB
se libere la nueva instancia cuando sale del alcance al asignar un método de instancia a un evento en una clase diferente, el resultado es que la nueva instancia de seB
vuelve inalcanzable desde nuestro código, pero todavía existe una referencia, lo que significa que el GC no la lanzará hasta quea
también esté fuera de alcance.Los eventos estáticos tienen el mismo escollo, ya que nunca salen del alcance, solo se limpian cuando finaliza el proceso, a menos que primero se dé de baja del evento. ¡Siempre almacene sus referencias, gente!
Lo anterior funciona con la misma idea, el controlador se vuelve inalcanzable una vez que el
while
bucle se sale del alcance, lo que hace imposible darse de baja del evento, lo que significa que la memoria se quedará allí hasta que el programa finalice. Los eventos estáticos son posiblemente más peligrosos que los eventos de instancia, porque puede asegurarse de que nunca se salgan del alcance.EDITAR : También puede hacer lo mismo básicamente con cualquier otro objeto, siempre que agregue una referencia y al mismo tiempo se asegure de que no haya forma de liberar esa referencia.
Aquí hay un ejemplo que usa objetos estáticos y matrices.
Las matrices se siguen agregando a la lista, pero no hay forma de borrar la lista sin modificar el código, lo que sería imposible para las aplicaciones de código cerrado. Aumentar el número pasado
Leak.Add
hará que se filtre más rápido, si lo configura lo suficientemente alto, solo se generará una excepción OverflowException inmediata.fuente
bash (sin utilidades externas)
No hay bomba tenedor aquí.
Advertencia: podría matar tu caparazón.
Solo trato de crear una matriz de enteros para referencia porque sigo olvidando cómo se ven los enteros.
Resultados en:
fuente
J (7)
ADVERTENCIA: Esto congeló mi sistema cuando lo probé (Windows 8, J 8.01, en el terminal qt).
2#
duplica la longitud del argumento duplicando cada elemento,^:_
encuentra el punto fijo de la función dada (pero no hay una, por lo que se repite sin parar)[_
lo llama_
como argumento.fuente
Haskell (número de Graham)
Es muy simple: calcula el número de Graham
A diferencia de otros ejemplos aquí, no se ejecutará para siempre ... usará mucha CPU, pero en teoría podría terminar. si no fuera por el hecho de que almacenar el número ...
(según wikipedia)
Entonces, la idea es que la memoria será utilizada por una (serie de cada vez más) enorme
Integer
(s) (los enteros de Haskell son de tamaño arbitrario).Si desea probarlo, es posible que deba aumentar el tamaño de la pila o cargarlo dentro
ghci
.fuente
Inspirado por @comintern.
Reemplazo / dev / null. Involucrando el modo furtivo. Requiere encabezados de kernel, modo de superusuario y un compilador que funcione.
Que te diviertas.
Makefile:
Código fuente:
¡Advertencia, esto puede obligarlo a reiniciar!
Para eliminarlo:
fuente
Rubí
Todos saben que suma (1 / n ^ 2) = pi ^ 2/6
Entonces puedo definir una función de aproximación:
Por supuesto, el (1..infinito) se volverá loco.
Sin embargo, tenga en cuenta que el uso de lazy hará que esto funcione;)
fuente
C -
2825 caracteres (programa completo)¡No ejecute ese, o su sistema se congelará rápidamente!
La llamada a malloc reservará 9 bytes de memoria y solicitará regularmente nuevas páginas de memoria al sistema operativo. La memoria asignada por malloc se filtra inmediatamente ya que no se almacena ningún puntero a la dirección devuelta. Una vez que el sistema se ha quedado sin memoria (RAM y espacio de intercambio) o se alcanza el límite de memoria para el proceso, el programa saldrá del ciclo while y terminará.
fuente
main(){while(malloc(9));}
guarda otros 3 caracteres y llena mi memoria casi instantáneamente.VBScript
Estamos creando un dicionario que apunta a sí mismo. Luego pensamos que destruimos el diccionario al establecerlo en Nothing. Sin embargo, el diccionario todavía existe en la memoria porque tiene una referencia válida (circular).
El bucle, pero también el problema de la memoria, hace que el programa se bloquee. Después de apagar el programa, la memoria todavía está en uso. El sistema solo se puede restaurar reiniciando.
fuente
Sí y tmpfs
¿Por qué escribir un nuevo programa cuando uno viene gratis con Ubuntu?
Como probablemente sepa, o ya lo ha adivinado, Ubuntu se monta / ejecuta / usuario / por defecto como tmpfs, que es un tipo de disco RAM .
Ni siquiera tiene que cerrarlo. Se cerrará cortésmente, dejando una buena porción de memoria asignada. Supongo
yes
es un programa de un solo proceso y un solo subproceso que no llama a ningún otro (escribir en un disco RAM existente también es trivialmente portátil para el idioma de su elección).Tiene un error menor: Ubuntu limita la escritura del usuario tmpfs / run / 1000 a 100 MB de forma predeterminada, por lo que es posible que la función de cambio de muerte no sea compatible con su máquina de fábrica. Sin embargo, logré arreglar esto en mi máquina con la siguiente solución rápida:
fuente
/run/user
directorio en absoluto. ¿Qué versión de Ubuntu usa y qué instaló para esto?tmpfs
sistema de archivos montado, puede enumerarlos condf -t tmpfs
. Mi sistema Ubuntu tiene un gran grande/run/shm
disponible ...Golpetazo
Advertencia: el siguiente código hará que su computadora no se pueda iniciar.
Advertencia: el código anterior hará que su computadora no se pueda iniciar.
Reemplace / dev / sda con su unidad de arranque. Esto escribe E8 FD FF al comienzo de su sector de arranque. Al arrancar, el BIOS lee su sector de arranque en la memoria y lo ejecuta. Esos códigos de operación son equivalentes a esta asamblea:
Esta es una recursión infinita, que eventualmente causará un desbordamiento de la pila.
fuente
jmp
lugar decall
Haskell
Esto intenta sumar los números de conteo. Haskell evalúa las sumas parciales, simplemente se convierte en una declaración de suma infinita. Si ejecuta el compilador con indicadores de optimización, es posible que no funcione.
fuente
Golpetazo
Ya que podemos utilizar los servicios públicos que no están diseñados específicamente para consumir memoria, me centro en una utilidad para liberar memoria:
swapon
. Esto se utiliza para permitir que el núcleo libere memoria escribiendo en el disco.Este script realiza dos optimizaciones: (1) Montaje de tmp como tmpfs (un tipo de disco RAM) para hacer / tmp más rápido y (2) crear un archivo de intercambio para liberar memoria. Cada uno de estos son razonables por sí mismos, pero si un usuario descuidado hace ambas cosas, establece un ciclo de intercambio: cuando el sistema operativo intenta intercambiar páginas, escribe en el tmpfs; esto hace que los tmpfs usen más memoria; Esto aumenta la presión de la memoria y hace que se intercambien más páginas. Esto puede tardar unos minutos en mi VM, mucho tiempo para que vea cómo el sistema se excava en un agujero utilizando
top
.Cerrar el programa hace poca diferencia ya que el programa en sí mismo apenas asigna memoria. De hecho, no es trivial liberar memoria ya que no puede liberar memoria desmontando el tmpfs antes que
swapoff
el archivo de intercambio, y eso es difícil de hacer hasta que haya liberado la memoria.Esta respuesta podría considerarse una historia de advertencia contra el cegamiento aplicando trucos geniales desde la red sin entenderlos.
fuente
Perl
Utiliza referencias circulares. El recuento de referencias para las variables nunca alcanzará 0, y las referencias nunca se recolectarán como basura.
Es posible que deba ser paciente, pero se garantiza que estrangulará su sistema. El disco comenzaría a girar más rápido y los humos podrían ser visibles.
fuente
PHP (solo Linux):
Este código no se ha probado, ya que no tengo una computadora Linux con php ejecutándose.
Pero esta es mi prueba de concepto:
Esto llenará la memoria con enormes imágenes RGBA (10000x10000 píxeles).
La única forma de apagar a este bebé es apagando la energía.
El código está todo comentado.
Cualquier mejora, duda, error o cualquier cosa, use el cuadro de comentarios a continuación.
fuente
Python - 56
Crea una clase, define un método para establecer atributos, establece un atributo en ella y crea una instancia inicial de la que luego intenta establecer un atributo.
Una simple función recursiva (
def f(x):f(x)
) parecía poco imaginativa, así que decidí no llamar nunca una función.La administración de memoria puede capturar la profundidad de recursión, pero realmente depende de la implementación.
Si esto es una bomba tenedor, por favor dígame.
fuente
RuntimeError: maximum recursion depth exceeded while calling a Python object
. Incluso establecer el límite máximo de recursiónsys.setrecursionlimit
casi sin memoria se usa antes de que falle con una falla de segmentación.Perl
Es simple, pero tenía ganas de jugar al golf.
Después de dos iteraciones,
$x
contiene una referencia a la matriz que contiene una referencia a la matriz que contieneundef
.El uso de la memoria es lineal en el tiempo, con pequeñas asignaciones, pero solo tardó varios segundos en ralentizar severamente mi administrador de ventanas en mi sistema Ubuntu Linux. Medio minuto después, el asesino de OOM se encargó de ello.
fuente
ECMAScript 6:
Sin golf:
Nota: Utiliza
setTimeout
, que se define como parte de Timers: el estándar de vida HTML .Pruébelo en Mozilla Firefox (puede pegarlo en la consola del desarrollador). Firefox sigue consumiendo más y más memoria, y usa
100%
la CPU en una máquina de un solo núcleo (en una máquina de 4 núcleos, como la mía, usa25%
la CPU). También tiene el beneficio adicional de que no puede detenerlo; si puedes abrir el administrador de tareas, puedes matar a Firefox con él.fuente
Golpetazo
Crear un archivo vacío
test
Reemplazar
/dev/null/
con este archivo de texto$ sudo mv test /dev/null
Esto funciona de manera similar a la respuesta de @Comintern. Toda la salida
/dev/null
ahora se agregará a este archivo de texto, que con el tiempo se volverá enorme y bloqueará el sistema.fuente
/dev
es adevtmpfs
, puede llenarse y obstaculizar el sistema. Supongo que esa es la intención de esta respuesta.Bash: 7 caracteres
Esta debería ser la solución bash más simple. Sin tenedores, sin trampas.
Se recomienda no ejecutar esto como root.
fuente
unset
la variable, la memoria permanece asignada hasta que se destruye el shell. Puedes ver la carnicería entop
.unset x
libera la memoria. pdksh también libera la memoria, pero ksh93 no puede liberarla, yexit
en ksh93 vuelca el núcleo.yes
se elimina, en cuyo punto simplemente permanece allí,unset
sin ningún efecto. Pero esto está en un sistema de memoria grande y tener una variable de varios gigabytes no parece molestarlo (hasta que finalmente decide matar el shell).C
Bueno, se necesita memoria página tras página y finalmente no queda memoria.
fuente
Rubí
Simplemente agrega infinitamente (¡recursivo!) Auto-referencias a sí mismo.
Me enteré de esta pequeña joya cuando alguien rompió mi caja de arena Ruby con ella . :RE
Demostración de los aspectos recursivos de la misma:
fuente
C ++ 79
No golf
Arreglé mi entrada para incluir la llamada de main.
fuente