Создать утечку памяти, без каких-либо вилочных бомб [закрыто]


54

Ваша задача - создать утечку памяти . Это программа, которая использует много памяти до тех пор, пока у компьютера не кончится нагрузка, и он должен выполнить некоторую подкачку, чтобы спасти себя от нехватки памяти. Единственный способ освободить память - убить программу в диспетчере задач или использовать команду командной строки, например taskkill /im yourprogram /f(в Windows), или даже перезагрузить компьютер. Простое закрытие приложения не должно мешать ему продолжать загружать память.

Правила:

  1. Любые вилочные бомбы запрещены. Это означает, что печально известная линия Bash:(){ :|:&};: запрещена!

  2. Приложение должно быть только однопоточным. Это подразумевает правило вилочной бомбы.

  3. Программа не должна запускать другие программы. Это означает, что вы не можете просто сделать что-то подобное run(memoryfiller.exe). Единственное исключение - это программы, которые поставляются в комплекте с вашей ОС или языком, которые не предназначены в первую очередь для потребления памяти (т. Е. Имеют другое назначение). Это значит, что такие вещи как catи ln -sразрешены.

  4. Вы можете занять столько памяти, сколько захотите. Чем больше, тем лучше.

  5. Код должен быть объяснен полностью.

Удачи. Это конкурс популярности, поэтому выигрывает код, набравший наибольшее количество голосов по истечении 10 дней с даты запроса!


8
«Закрытие должно по-прежнему превращать его в излишнюю память» - если программа является исполняемой оболочкой (как и большинство оконных версий интерпретаторов языка сценариев), закрытие ее окна убьет программу.
Мниип

54
Разве это не просто while(1)malloc(999);?
Дверная ручка

10
Я не уверен, совместимо ли «Закрытие должно сделать его запоминающим устройством» с «Приложение должно быть только однопоточным». Если ни один поток не имеет куска памяти, ОС может вернуть его обратно, верно?
aebabis

51
Просто запустите Firefox 26 с несколькими открытыми вкладками и запустите flash в течение получаса. Это поставит ваш компьютер на колени.
Брэден Бест

1
@mniip. Вот и весь смысл проблемы. Чтобы сделать сложный вызов. И дверная ручка. Я хотел что-то другое! ;)
Джордж

Ответы:


78

Windows

Win32 API позволяет выделять память в других процессах, а затем удаленно читать / записывать эту память. Эта программа имеет только один поток, который она использует для перечисления каждого запущенного процесса в системе, а затем многократно выделяет 1 МБ буферов в каждом процессе, пока распределение не завершится неудачно. Когда он заканчивается одним процессом, он переходит к следующему. Распределения не освобождаются, когда вызывающая программа заканчивается - только когда / если заканчивается каждый целевой процесс. Это приводит к зависанию виртуальной машины Windows 7 объемом 2 ГБ примерно за 10 секунд. Это требует запуска от имени администратора.

Скомпилировать: cl /MD leak.cpp /link psapi.lib

#include <windows.h>
#include <psapi.h>

typedef void (*ProcFunc)(DWORD pid);
#define ALLOC_SIZE 0x100000
LPVOID buf;

void ForEachProcess(ProcFunc f)
{
    DWORD aProcesses[1024], cbNeeded;

    if (!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded))
        return;

    for (unsigned int i = 0; i < cbNeeded / sizeof(DWORD); i++)
        if (aProcesses[i] != 0)
            f(aProcesses[i]);
}

void RemoteLeak(DWORD pid)
{
    HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
    if (hProcess == NULL)
        return;

    for (;;)
    {
        LPVOID ptr = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, 
                                    MEM_COMMIT, PAGE_READWRITE);
        if (ptr == NULL)
            return;

        WriteProcessMemory(hProcess, ptr, buf, ALLOC_SIZE, NULL);
    }
}

int main(void)
{
    buf = malloc(ALLOC_SIZE);
    if (buf == NULL)
        return 0;

    memset(buf, 0xFF, ALLOC_SIZE);

    ForEachProcess(RemoteLeak);

    return 0;
}

9
Windows это зло.
Томсминг

4
Мне нужно закрыть сегодня вечером. Я попробую;)
Джордж

1
«(работает как обычный пользователь, не используя привилегий администратора» - не уверен в этом, вам нужен SeDebugPrivilege, которого по умолчанию нет в токене обычного пользователя
rkosegi

@rkosegi Спасибо, исправлено.
Эндрю Медико

14
+1 Это заслуживает многих откликов, так как пока что это единственный ответ, который соответствует первоначальному закрытию. Это все равно должно привести к увеличению потребности в памяти . Очень креативное решение :-)
Daniel

72

Ява

import java.util.concurrent.atomic.AtomicInteger;

public class Hydra {
  // Not actually necessary for the leak - keeps track of how many Hydras there are, so we know when they're all gone
  public static AtomicInteger count = new AtomicInteger(0);
  public Hydra() {
    count.incrementAndGet();
  }
  protected void finalize() {
    new Hydra();
    new Hydra();
    count.decrementAndGet();
  }

  public static void main(String[] args) throws InterruptedException {
    new Hydra();
    while (Hydra.count.get() > 0) {
      // Prevent leaks ;-)
      System.gc();
      System.runFinalization();
    } 
  }
}

объяснение

Вы можете предположить, что, поскольку в коде нет ссылок (кроме тех count, которые вы можете спокойно игнорировать), он не может просочиться. Тем не менее, финализатор создает две новые гидры, и хотя он не содержит ссылок на них, они будут зависать до тех пор, пока не будут завершены. Это означает, что программа выполняет утечку памяти только во время сборки мусора - отсюда и вызовы System.gc()и System.runFinalization().


7
@TimS. где твой Бог сейчас?!?
Cruncher

Есть System.gc()и System.runFinalization()необходимо? То есть будет ли иногда запускаться gc случайно, или вам придется либо заполнить какую-то память, либо вызвать gc?
Cruncher

4
В типичной программе System.gc()и System.runFinalization()не было бы необходимости. Сборка мусора происходит естественным образом из-за нехватки памяти. Однако в этом приложении отсутствует нагрузка на память, пока не начнется сбор мусора. Я думал об искусственном введении некоторых (например, перемещаясь new Hydra()внутри цикла), но подумал, что это было больше зла.
James_pic

1
Да, я не обращал особого внимания на предостережение: «Закрытие должно все равно сделать его забитым памятью», так как это не казалось осмысленным (кроме аккуратных хаков ОС, таких как @ german_guy's) Java всегда раскручивает поток завершения, поэтому, возможно, у приложения Java нет способа подчиниться правилу № 2.
James_pic

1
В системах Unix вы не можете блокировать SIGKILL (сигнал 9), поэтому вы не можете сделать свою программу неостановимой (ну, разве что если вам удастся перевести ее в состояние непрерывного ожидания ... так что, возможно, удаленное уничтожение сервера NFS, файлы которого вы доступ может работать ;-))
celtschk

37

С

Использование языка программирования C и протестировано с ядром Linux 2.6.32-49-generic и libc-2.11.1.so.

Единственный способ освободить память - убить программу в диспетчере задач или использовать taskkill / im yourprogram / f или даже перезагрузить компьютер.

Это достигается блокировкой любых сигналов, кроме SIGKILL и SIGSTOP.

Закрытие должно все еще сделать это памятью свиньи.

Это на самом деле смутило меня ... и его удаление, или закрытие приводит к завершению процесса, позволяя операционной системе вернуть себе любую память, выделенную этому процессу. Но потом я подумал, что закрывая его, вы можете закрыть терминал или любой другой родительский процесс, который выполняет процесс утечки памяти. Если я правильно понял, то решил эту проблему, заблокировав все сигналы, которые превращают процесс в демон, когда родительский процесс завершается. Таким образом, вы можете закрыть терминал, в котором запущен процесс, и он продолжит работу и продолжит утечку памяти.

Любые вилочные бомбы запрещены. Это означает, что печально известный bash: () {: |: &} ;: забанен!

Процесс не развивается.

Приложение должно быть только однопоточным. Это подразумевает правило вилочной бомбы

Новые темы не создаются.

Программа не должна запускать другую программу. Это означает, что вы не можете просто сделать что-то вроде запуска (memoryfiller.exe)

Новые процессы не создаются.

Вы можете занять столько памяти, сколько захотите. Чем больше, тем лучше.

Столько, сколько может обеспечить операционная система.

Код должен быть объяснен полностью.

Добавлены комментарии к источнику.

И, наконец, вот код:

#define _GNU_SOURCE

#include <stdio.h>
#include <signal.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>


int main(int argc, char* argv[]) {

    /*
    set the real, effective and set user id to root,
    so that the process can adjust possible limits.
    if the process doesn't have the CAP_SETUID capability, terminate the process.
    */
    if (setresuid(0, 0, 0) == -1) {
        printf("Are you root?!\n");
        return 1;
    }

    /*
    block all signals except for kill and stop.
    this allows to terminate the parent process (most likely a terminal)
    that this process is running in and turn it into a daemon.
    additionally this makes it impossible to terminate the process
    in a normal way and therefore satisfies the requirement that closing
    it should still make it hog memory.
    */
    sigset_t mask;
    sigfillset(&mask);
    sigprocmask(SIG_SETMASK, &mask, NULL);

    /*
    allow the process to acquire a virtually unlimited amount of memory
    and queue a virtually unlimited amount of signals.
    this is to prevent an out of memory error due to a virtual limit for the root user,
    which would prevent the process from leaking any more memory
    and to prevent the process from getting killed due to too many queued
    signals that the process is blocking.
    */
    struct rlimit memory = { RLIM_INFINITY, RLIM_INFINITY },
                  signal = { RLIM_INFINITY, RLIM_INFINITY};
    setrlimit(RLIMIT_AS, &memory);
    setrlimit(RLIMIT_SIGPENDING, &signal);

    /*
    allocate a buffer big enough to store a file name into it
    that is generated from the process' pid.
    if the file can be opened (which should always be the case unless /proc is not mounted)
    the file will be opened and the string -17 followed by a new line written to it.
    this will cause the oom killer to ignore our process and only kill other,
    innocent processes when running out of memory.
    */
    char file_name[20];
    sprintf(file_name, "/proc/%u/oom_adj", getpid());

    FILE* oom_killer_file = fopen(file_name, "w");
    if (oom_killer_file) {
        fprintf(oom_killer_file, "-17\n");
        fclose(oom_killer_file);
    }

    /*
    get the size of virtual memory pages in bytes,
    so the process knows the size of chunks that have to be
    made dirty to force the kernel to map the virtual memory page into RAM.
    */
    long page_size = sysconf(_SC_PAGESIZE);

    // allocate a virtually infinite amount of memory by chunks of a page size.
    while(1) {
        // will overwrite any previous stored address in tmp, leaking that memory.
        char* tmp = (char*) malloc(page_size);
        if (tmp)
            // make the memory page dirty to force the kernel to map it into RAM.
            tmp[0] = 0;
    }

    return 0;
}

Для всех, кто интересуется, что произойдет, если вы продолжите работать с этой программой: в моей тестовой системе с 2 ГБ ОЗУ и 4 ГБ подкачки места потребовалось около 10 минут для заполнения ОЗУ и подкачки. Убийца OOM начал свою работу, и через три минуты все процессы были убиты. Даже мышь, клавиатура и дисплей были сброшены системой. /var/log/kern.log не показывает никакой полезной информации, кроме процессов, которые были убиты.


Я отредактировал исходный код, чтобы заставить oom killer игнорировать процесс и вместо этого убивать невинные процессы, чтобы освободить память.
Foobar

5
Для всех, кто интересуется, что произойдет, если вы продолжите работать с этой программой: в моей тестовой системе с 2 ГБ ОЗУ и 4 ГБ подкачки места потребовалось около 10 минут для заполнения ОЗУ и подкачки. Убийца OOM начал свою работу, и через три минуты все процессы были убиты. Даже мышь, клавиатура и дисплей были сброшены системой. /var/log/kern.log не показывает никакой полезной информации, кроме процессов, которые были убиты.
foobar

Ха-ха, это прекрасно! Вы должны отредактировать это описание в своем ответе. +1
дверная ручка

1
Я не понизил голосование, но было бы неплохо, если бы код мог быть отформатирован, поэтому для чтения комментариев не требуется горизонтальная прокрутка.
Пауло Эберманн

2
+1 за 1) уничтожение процессов, передающих устройства ввода / вывода, и 2) создание программы, которую трудно отследить из журналов. Это завитые усами уровни зла.
Кевин - Восстановить Монику

29

Чистый Баш

Я не обещаю

:(){ : $@$@;};: :

Он очень похож на вилочную бомбу и использует похожую рекурсивную технику, но без вилок. Конечно, это приведет к запуску вашей оболочки прямо из памяти, поэтому рекомендуется вставить новую оболочку перед вставкой этой команды.

  • Определите функцию под названием :
  • Функция просто рекурсивно вызывает себя с $@удвоенным (список аргументов)
  • После определения :функции функция вызывается с начальным аргументом:

Выход:

$ bash
$ :(){ : $1$1;};: :
bash: xmalloc: ../bash/stringlib.c:135: cannot allocate 536870913 bytes (5368795136 bytes allocated)
$

В предыдущей редакции этого ответа я это сделал a=$(yes), но заметил правило «Программа не должна запускать другую программу», поэтому мне нужно использовать pure bashвместо вызова coreutils или чего-либо еще.


Вот еще один:

ПОЖАЛУЙСТА, НЕ ПРОПУСТИТЕ ЭТО НА ПРОИЗВОДСТВЕННОМ МАШИНЕ

:(){ : <(:);};:

Опять же, это не вилочная бомба - все запускается изнутри. Похоже, что это очень удобно поставить мою Ubuntu VM на колени, с небольшим пространством для восстановления, кроме перезагрузки.

Как и в классической вилочной бомбе, рекурсивная функция :()определена. Однако он не раскладывает звонки самому себе. Вместо этого он вызывает себя с одним аргументом, который сам вызывается в подстановке процесса . Поскольку подстановка процессов работает путем открытия файлового дескриптора /dev/fd/n, это не только израсходует память процесса (bash), но и немного памяти ядра. На моей машине с Ubuntu это приводит к неработоспособности оконного менеджера через несколько секунд, а затем вскоре после появления этого экрана:

enter image description here

Нажатие OKзатем дает этот экран:

enter image description here

Похоже, что ни один из этих вариантов не очень помогает - на данный момент перезапуск кажется единственным хорошим вариантом.


3
$ which yes->/usr/bin/yes
Изката

2
«Единственный способ освободить память - это убить программу в диспетчере задач или использовать taskkill / im yourprogram / f или даже перезагрузить компьютер. Закрытие должно по-прежнему превращать память в излишнюю память». >> bash может быть прерван с помощью SIGTERM, поэтому для его остановки не требуется уничтожение. Также он перестает работать, когда системе не хватает памяти. После завершения bash, либо SIGTERM, либо из-за нехватки памяти, память возвращается операционной системе.
Фубар

Это не работает для меня ... вроде ... Я вижу, как память постепенно уходит, но это происходит очень медленно, и это также можно убить, просто нажав Ctrl + C. Сейчас он работает в течение 1 минуты и занимает около 1 ГБ. У меня ОЧЕНЬ быстрая машина ... но это не должно иметь значения, верно?
Стефанос Калантзис

Отвечая на мой собственный комментарий: команда фактически убила bash примерно через 2 минуты 49 секунд. Первоначально я предполагал, что это мгновенно, основываясь на этом ответе.
Стефанос Калантзис

@StefanosKalantzis Спасибо за ваши комментарии. Это заставило меня задуматься, и я нашел еще более злой фрагмент оболочки - см. Правку.
Цифровая травма

24

XML

<!DOCTYPE boom [
<!ENTITY Z 'ka-boom!'><!ENTITY Y '&Z;&Z;'><!ENTITY X '&Y;&Y;'><!ENTITY W '&X;&X;'>
<!ENTITY V '&W;&W;'><!ENTITY U '&V;&V;'><!ENTITY T '&U;&U;'><!ENTITY S '&T;&T;'>
<!ENTITY R '&S;&S;'><!ENTITY Q '&R;&R;'><!ENTITY P '&Q;&Q;'><!ENTITY O '&P;&P;'>
<!ENTITY N '&O;&O;'><!ENTITY M '&N;&N;'><!ENTITY L '&M;&M;'><!ENTITY K '&L;&L;'>
<!ENTITY J '&K;&K;'><!ENTITY I '&J;&J;'><!ENTITY H '&I;&I;'><!ENTITY G '&H;&H;'>
<!ENTITY F '&G;&G;'><!ENTITY E '&F;&F;'><!ENTITY D '&E;&E;'><!ENTITY C '&D;&D;'>
<!ENTITY B '&C;&C;'><!ENTITY A '&B;&B;'><!ENTITY z '&A;&A;'><!ENTITY y '&z;&z;'>
<!ENTITY x '&y;&y;'><!ENTITY w '&x;&x;'><!ENTITY v '&w;&w;'><!ENTITY u '&v;&v;'>
<!ENTITY t '&u;&u;'><!ENTITY s '&t;&t;'><!ENTITY r '&s;&s;'><!ENTITY q '&r;&r;'>
<!ENTITY p '&q;&q;'><!ENTITY o '&p;&p;'><!ENTITY n '&o;&o;'><!ENTITY m '&n;&n;'>
<!ENTITY l '&m;&m;'><!ENTITY k '&l;&l;'><!ENTITY j '&k;&k;'><!ENTITY i '&j;&j;'>
<!ENTITY h '&i;&i;'><!ENTITY g '&h;&h;'><!ENTITY f '&g;&g;'><!ENTITY e '&f;&f;'>
<!ENTITY d '&e;&e;'><!ENTITY c '&d;&d;'><!ENTITY b '&c;&c;'><!ENTITY a '&b;&b;'>
]>
<boom a="&a;"/>

Затем передайте документ синтаксическому анализатору XML, который не выполняет циклическое / рекурсивное обнаружение ссылки на сущность. Например, xpathвключено в Perl:

xpath boom.xml /

Как это устроено:

  1. Парсер встречает <boom a="&a;">
  2. Парсер расширяется "&a;"в"&b;&b;"
  3. Синтаксический анализатор расширяет одно из "&b;"в "&c;&c;"(по возвращении это расширит другое "&b;")
  4. Парсер расширяет один из "&c;"etc ...

Если бы могло произойти полное расширение, было бы 2 ^ 52 расширение "ka-boom!". Предполагая 2 байта на символ, он попытается использовать 64 ПиБ. Расширение идет "ка-бум!" за один раз, так что вы можете обычно смотреть, как он использует всю память сверху.

Это называется разными именами, хороший обзор здесь: http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion



@ColeJohnson Да это все! Я участвовал в проекте классификации угроз WASC, поэтому я чувствовал себя обязанным указывать на WASC, а не на Википедию. :)
ɲeuroburɳ

22

C ++

int main()
{
    for(;;)int *a=new int;
}

Этот код был неожиданным! Он повесил мой компьютер, когда был открыт диспетчер задач, и показал, что он занял 890 Мб памяти за 1 секунду, а затем завис. Я не знаю, как это работает, может быть, он продолжает выделять память для переменной. Чтобы изучить больше этого кода, я добавил оператор, delete a;и все было хорошо во время тестирования (без зависаний). Итак, я думаю, что кусок памяти отдано (из-за new int) и затем возвращено (из-за delete a) в свободное место в новом коде ниже.

int main()
{
    for(;;)
    {
         int *a=new int;
         delete a;
    }
}  

Итак, я делаю вывод, что ОЗУ В ЭТОМ МИРЕ НЕ МОЖЕТ ОБРАЩАТЬСЯ С ЭТИМ КОДОМ !!!

РЕДАКТИРОВАТЬ : Но многие процессоры могут, например, intel core 2 duoне могут обработать этот код, но
intel core i-series могут (работал для меня ...)

Помните, что ответом на вопрос является 1-й код, второй - для объяснения.


9
Хорошо, компилятор думает, что вы все еще собираетесь использовать new intдаже если вы перезаписали указатель, поэтому вы никогда не сможете получить к нему доступ снова ... Таким образом, сборка мусора не вызывается, и вы заполняете память быстрее, чем толстый ребенок ест кегли
Дэвид Уилкинс

37
@DavidWilkins: ... это C ++, C ++ не имеет сборщика мусора.
Phoshi

32
Если для вас неожиданно произойдет утечка этого кода, то я думаю, что вы не должны использовать C ++, пока не изучите его лучше.
svick

1
@svick Но это не то же самое, что ударять в дартс в темноте! У меня была идея, что это сделает вопрос о работе.
Мукул Кумар

15
@svick Как, черт возьми, он должен «учиться лучше», если он «не должен использовать C ++»?
Кевин

16

Brainfuck

+[>+]

Объяснение:

Чтобы войти в цикл, он увеличивает ячейку до 1. Он перемещается к следующей ячейке, увеличивая ее до 1, пока последняя ячейка была положительной.

Обычно в интерпретаторе BrainFuck имеется жесткое ограничение количества ячеек на ленте, но некоторые интерпретаторы добавляют ячейки динамически. Они будут продолжать потреблять память, пока она больше не будет потреблять.

beefэто один из таких интерпретаторов, и он доступен в Центре программного обеспечения Ubuntu, и мой текущий запуск на неиспользуемой машине начался 29 часов назад и за это время потребил 1 ГБ ОЗУ. Вот выходtop

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 1030m 984m 2536 R 100,1 12,4   1750:52 beef

Он имеет 4 ГБ кэш-памяти и 6 ГБ подкачки, так что я думаю, что я обновлю этот ответ с тем, как он прошел примерно через 12 дней.

ОБНОВЛЕНИЕ 03.24 17:11

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 1868m 1,8g 2456 R  99,9 22,9   6008:18 beef    

ОБНОВЛЕНИЕ 03.31 00:20

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 2924m 2,8g 2052 R 100,0 36,1  15019:46 beef   

Так что это работает в течение 10 дней. Похоже, он будет работать еще как минимум 10, прежде чем произойдет что-то интересное.


Хороший и короткий.
nrubin29

15

C и POSIX

Здесь я стремлюсь к очень портативному решению. Проблема в том, что чистый C, похоже, не может сказать операционной системе, что память должна оставаться выделенной после закрытия программы. Поэтому я позволю себе использовать POSIX; большинство ОС имеют некоторые претензии на совместимость с POSIX, включая Windows, Linux и MacOS X. Однако я тестировал его только на Ubuntu 12.04 32bit. Не требует прав суперпользователя.

Это решение по сути является традиционным while(1){malloc(1);}решением. Однако вместо malloc он использует функции совместно используемой памяти POSIX. Поскольку он назначает идентификатор общей памяти каждому выделению, все еще возможно получить доступ к памяти, как только процесс завершается. Таким образом, ядро ​​не может освободить память.

#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>

#define SHMSZ (2*1024*1024) /*Ubuntu rejects shared allocations larger than about 2MiB*/

main() {
  int shmid;
  key_t key = 0xF111; /* Lets use `Fill' as our first ID.*/
  char *shm;

  while(1) { /* Like malloc, but using shared memory */
    if ((shmid = shmget(key, SHMSZ, IPC_CREAT|0666)) < 0){return 1;}/*Get shared memory*/
    if ((shm = shmat(shmid, NULL, 0)) == (void *) -1) { return 1; } /*Attach it        */
    memset(shm,0,SHMSZ);                                            /*Fill it up       */
    key++                                                           /*On to the next ID*/
  }
}

Лучший и самый блестящий ответ С ИМО. +1
syb0rg

1
Хороший. Первым решением, которое я придумал, было решение Andrew Medico, но так как это невозможно в Linux, и поскольку я не люблю программирование Windows, я хотел просочиться через общую память, но не мог вспомнить имена функций POSIX. Спасибо, что вспомнили обо мне;) Все, что я нашел, было только mmap, которое не отображено при завершении процесса ...
foobar

14

C #

Если вы забудете отписаться от событий до того, как обработчик выйдет из области видимости, .NET вызовет утечку памяти, пока не возникнет исключение OutOfMemoryException.

using System;

class A
{
    public event Action Event;
}

class B
{
    public void Handler() { }
}

class Program
{
    static void Main()
    {
        A a = new A();

        while( true )
            a.Event += new B().Handler;
    }
}

Объяснение : Внутри whileцикла мы создаем новый объект, заставляя каркас выделять больше памяти, но мы также предотвращаем Bосвобождение нового экземпляра , когда он выходит из области видимости, назначая метод экземпляра событию в другом классе, в результате новый экземпляр Bстановится недоступным из нашего кода, но ссылка все еще существует, то есть GC не выпустит его, пока aтакже не выйдет из области видимости.

Статические события имеют одну и ту же ловушку, так как они никогда не выходят за рамки, они очищаются только после завершения процесса, если вы сначала не отмените подписку на событие. Всегда храните ваши отзывы, люди!

using System;

class Program
{
    static event Action Event;

    static void Main()
    {
        while( true )
            Event += new Action( delegate{ } );
    }
}

Вышеприведенное работает по той же идее, обработчик становится недоступным, как только whileцикл выходит из области видимости, что делает невозможным отписаться от события, то есть память будет находиться там до завершения программы. Статические события, возможно, более опасны, чем события экземпляра, потому что вы можете быть уверены, что они никогда не выйдут за рамки.

РЕДАКТИРОВАТЬ : Вы также можете сделать то же самое с любым другим объектом, если вы добавляете ссылку, в то же время гарантируя, что нет никакой возможности освободить эту ссылку.

Вот пример, который использует статические объекты и массивы.

using System;
using System.Collections.Generic;

static class Leak
{
    private static List<decimal[]> Junk;

    static Leak()
    {
        Junk = new List<decimal[]>();
    }

    public static void Add( uint size )
    {
        decimal[] arr = new decimal[size];
        Junk.Add( arr );
    }
}

class Program
{
    static void Main()
    {
        while( true )
            Leak.Add( 1 );
    }
}

Массивы продолжают добавляться в список, но нет способа очистить список без изменения кода, что было бы невозможно для приложений с закрытым исходным кодом. Увеличение передаваемого числа Leak.Addвызовет более быструю утечку, если вы установите его достаточно высоко, это вызовет немедленное возникновение исключения OverflowException.


10

bash (без внешних утилит)

Здесь нет вилочной бомбы.

Предупреждение: это может убить вашу оболочку.

Просто пытаюсь создать массив целых чисел для справки, потому что я постоянно забываю, как выглядят целые числа.

while :; do _+=( $((++__)) ); done

Результаты в:

xmalloc: expr.c:264: cannot allocate 88 bytes (268384240 bytes allocated)

2
+1 за "потому что я все время забываю, как выглядят целые числа" :)
Дэвид Конрад

8

J (7)

ВНИМАНИЕ: Это заморозило мою систему, когда я попробовал ее (Windows 8, J 8.01, в терминале qt).

2#^:_[_
  • 2# удваивает длину аргумента, дублируя каждый элемент,
  • ^:_ находит точку фиксации данной функции (но ее нет, поэтому она зацикливается бесконечно),
  • [_называет это _как аргумент.

8

Хаскелл (номер Грэма)

Это очень просто: это вычисляет число Грэма

В отличие от других примеров здесь, он не будет работать вечно ... он будет использовать много процессоров, но теоретически он может завершиться. если бы не тот факт, что хранить номер ...

наблюдаемая вселенная слишком мала, чтобы содержать обычное цифровое представление числа Грэма, предполагая, что каждая цифра занимает один том Планка .

(согласно википедии)

import Data.Sequence
import Data.Foldable

(↑) a 1 b = a ^ b
(↑) a _ 0 = 1
(↑) a i b = a ↑ (i-1) $ a ↑ i $ b-1

graham = last $ toList $ iterateN 64 (\i -> 3 ↑ i $ 3) 4
main = print graham

Таким образом, идея заключается в том, что память будет использоваться (серией все более и более) огромных Integer(s) (целые числа Хаскелла имеют произвольный размер).

Если вы хотите проверить это, вам, возможно, придется увеличить размер стека или загрузить его внутрь ghci.


2
Тупая вселенная, не соответствующая стандарту Хаскелла для целых чисел. Почему он не может поддерживать произвольный размер?
PyRulez

6

Вдохновленный @comintern.

Замена / dev / null. Включение подлого режима. Требуются заголовки ядра, режим суперпользователя и работающий компилятор.

# make
# rm /dev/null
# insmod devnull.ko
# chmod go+rw /dev/null

Веселиться.

Makefile:

MODULE := devnull
KVERS  ?= $(shell uname -r)
KDIR   ?= /lib/modules/$(KVERS)/build
KMAKE := make -C $(KDIR) M=$(PWD)

obj-m += $(MODULE).o

all:
    $(KMAKE) modules

install:
    $(KMAKE) modules_install

clean:
    $(KMAKE) clean

Исходный код:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>

#define DEVICE_NAME "null"
#define MAJOR_NUMBER 0

MODULE_LICENSE("GPL");
MODULE_AUTHOR("nola <florian@n0la.org>");
MODULE_DESCRIPTION("/dev/null - memory leak style");
MODULE_VERSION("0.1");
MODULE_SUPPORTED_DEVICE("null");

static struct class *class_null;
static int major = 0;

static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static loff_t device_llseek(struct file *, loff_t, int);

static struct file_operations fops = {
    .owner = THIS_MODULE,
    .llseek = &device_llseek,
    .read = &device_read,
    .write = &device_write,
    .open = &device_open,
    .release = &device_release
};

static int __init mod_init(void)
{
    struct device *dev_null;

    if ((major = register_chrdev(MAJOR_NUMBER, DEVICE_NAME, &fops)) < 0) {
        return major;
    }

    /* create /dev/null
     * We use udev to make the file.
     */
    class_null = class_create(THIS_MODULE, DEVICE_NAME);
    if (IS_ERR(class_null)) {
        unregister_chrdev(major, DEVICE_NAME);
        return -EIO;
    }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
    dev_null = device_create(class_null, NULL, MKDEV(major, 0),
                             NULL, "%s", DEVICE_NAME
        );
#else
    dev_null = device_create(class_null, NULL, MKDEV(major, 0),
                             "%s", DEVICE_NAME
        );
#endif
    if (IS_ERR(dev_null)) {
        class_destroy(class_null);
        unregister_chrdev(major, DEVICE_NAME);
        return -EIO;
    }

    return 0;
}

static void __exit mod_exit(void)
{
    device_destroy(class_null, MKDEV(major, 0));
    class_unregister(class_null);
    class_destroy(class_null);
    unregister_chrdev(major, DEVICE_NAME);
}

static int device_open(struct inode *inode, struct file *file)
{
    file->f_pos = 0x00;

    try_module_get(THIS_MODULE);
    return 0;
}

static int device_release(struct inode *inode, struct file *file)
{
    /* decrement usage count: Not. Uncomment the line for less fun. */
    /* module_put(THIS_MODULE); */
    return 0;
}

static loff_t device_llseek(struct file *filep, loff_t offs, int mode)
{
    loff_t newpos;

    switch (mode) {
    case 2:
    case 0:
        newpos = offs;
        break;

    case 1:
        newpos = filep->f_pos + offs;
        break;

    default:
        return -EINVAL;
    }

    if (newpos < 0) {
        return -EINVAL;
    }

    filep->f_pos = newpos;

    return newpos;
}

static ssize_t device_read(struct file *filep, char *dst, size_t len,
                           loff_t *off)
{
    char *buf = NULL;

    if (dst == NULL || len == 0) {
        return -EINVAL;
    }

    buf = kmalloc(sizeof(char) * len, GFP_KERNEL);
    if (buf == NULL) {
        return -EINVAL;
    }

    /* Do how a /dev/null does.
     */
    memset(dst, 0, len);

    *off += len;
    return len;
}

static ssize_t device_write(struct file *filep, const char *src, size_t len,
                            loff_t *off)
{
    char *buf = NULL;

    buf = kmalloc(sizeof(char) * len, GFP_KERNEL);
    if (buf == NULL) {
        return -EINVAL;
    }

    *off += len;
    return len;
}

module_init(mod_init);
module_exit(mod_exit);

Предупреждение это может заставить вас перезагрузиться!

Чтобы удалить это:

# rmmod -f devnull # or a reboot
# rm -rf /dev/null
# mknod /dev/null c 1 3
# chmod go+rw /dev/null

6

Рубин

Всем известно, что сумма (1 / n ^ 2) = pi ^ 2/6

Таким образом, я могу определить функцию приближения:

pi_approx = lambda {|i|
Math.sqrt( 
  6*( 
    (1...Float::INFINITY).map{|n| n.to_f**(-2)}.take(i).reduce(:+)
    )
  )
}

p pi_approx.(100_000)

Конечно (1..infinity) станет диким.

Однако обратите внимание, что использование lazy сделает эту работу;)

pi_approx = lambda {|i|
Math.sqrt( 
  6*( 
    (1...Float::INFINITY).lazy.map{|n| n.to_f**(-2)}.take(i).reduce(:+)
    )
  )
}

p pi_approx.(100_000)
#=> 3.141583104326456

5

C - 28 25 символов (полная программа)

Не запускайте его, иначе ваша система быстро зависнет!

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

При вызове malloc резервируется 9 байт памяти и регулярно запрашиваются новые страницы памяти у операционной системы. Память, выделенная функцией malloc, немедленно просачивается, поскольку указатель на возвращаемый адрес не сохраняется. Как только система исчерпает память (ОЗУ и пространство подкачки) или будет достигнут предел памяти для процесса, программа выйдет из цикла while и завершит работу.


2
Недолго - любая достаточно современная система должна иметь OOM-убийцу, который запускает и убивает процесс. По крайней мере, Ubuntu 12.04 делает.
Цифровая травма

1
Ну, я разбил свой Ubuntu 13.10, пытаясь этот код ...
Матье Родик

@DigitalTrauma Например, есть ли у FreeBSD OOMK?
Руслан

1
main(){while(malloc(9));}сохраняет еще 3 символа и заполняет мою память практически мгновенно.
Gmatht

@gmatht: спасибо за предложение! Я отредактировал ответ ... хотя мне понравилась идея увеличения размера блока в каждом цикле.
Матье Родик,

4

VBScript

do
    Set d1 = createobject("Scripting.Dictionary")
    d1.add true, d1
    Set d1 = Nothing
loop

Мы создаем дичионар, который указывает на себя. Затем мы думаем, что уничтожаем словарь, устанавливая его в Nothing. Тем не менее, словарь все еще существует в памяти, потому что он имеет действительную (круговую) ссылку.

Цикл, а также память, заставляет программу зависать. После выключения программы память все еще используется. Система может быть восстановлена ​​только после ее перезапуска.


Ну правда? VBScript не просто использует VB.NET под капотом? Циркулярные ссылки обычно не являются проблемой для сборщиков мусора, за исключением простых реализаций подсчета ссылок, и завершение программы должно привести к освобождению всей кучи, не так ли?
Дэвид Конрад

@DavidConrad Вы бы так подумали, но мне приходилось перезагружать компьютер каждый раз, когда я исследовал это и запускал сценарии такого типа.
AutomatedChaos

1
VBScript значительно предшествует VB.Net - это не версия командной строки VB.Net; это интерпретируемое подмножество устаревшей Visual Basic.
Крис Дж

Спасибо вам обоим Я не понимал, каковы были отношения между VBScript и VB.NET.
Дэвид Конрад

4

Да и tmpfs

Зачем писать новую программу, если вы приходите бесплатно с Ubuntu?

yes > /run/user/$UID/large_file_on_my_ramdisk

Как вы, наверное, знаете или уже догадались, Ubuntu по умолчанию монтирует / run / user / как tmpfs, который является типом RAM-диска .

Вам даже не нужно закрывать это. Он будет вежливо закрываться, оставляя хороший кусок памяти. Я предполагаю, yesчто это однопоточная, однопроцессная программа, которая не вызывает никаких других (запись на существующий RAM-диск также легко переносится на язык по вашему выбору).

В ней есть небольшая ошибка: Ubuntu по умолчанию ограничивает доступную для записи tmpfs / run / 1000 до 100 МБ, поэтому функция смерти свопинга может не поддерживаться на вашем компьютере из коробки. Однако мне удалось исправить это на моей машине следующим быстрым решением:

sudo mount -o remount,size=10G tmpfs /run/user/

У меня нет /run/userкаталога вообще. Какую версию Ubuntu вы используете и что для этого установили?
Руслан

Убунту Трасти Тар (14.04). Специальной установки не требуется.
Gmatht

Чтобы узнать, установлены ли у вас какие-либо tmpfsфайловые системы, вы можете перечислить их с помощью df -t tmpfs. У моей системы Ubuntu есть прекрасный большой /run/shmдоступный ...
Тоби Спайт

4

удар

Предупреждение: следующий код сделает ваш компьютер не загружаемым.

printf "\\xe8\\xfd\\xff" | dd of=/dev/sda
reboot

Предупреждение: предыдущий код сделает ваш компьютер не загружаемым.

Замените / dev / sda загрузочным диском. Это пишет E8 FD FF в начало вашего загрузочного сектора. При загрузке BIOS считывает ваш загрузочный сектор в память и выполняет его. Эти коды операций эквивалентны этой сборке:

label:
  call label

Это бесконечная рекурсия, которая в конечном итоге приведет к переполнению стека.


В вашем примере на ассемблере вы могли бы сохранить символ (при условии, что имя «label» необходимо), используя jmpвместоcall
SirPython

call оставляет адрес возврата в стеке для ret. прыжок не вызовет переполнение стека.
Джерри Иеремия

3

Haskell

main=print $ sum [0..]

Это пытается сложить счетные числа. Haskell вычисляет частичные суммы, он просто становится бесконечным оператором сложения. Если вы запустите компилятор с флагами оптимизации, он может не работать.


3

удар

Так как мы можем использовать утилиты, специально не предназначенные для потребления памяти, я остановлюсь на полезность для свободной памяти: swapon. Это используется, чтобы позволить ядру освободить память путем записи на диск.

Этот скрипт выполняет две оптимизации: (1) монтирование tmp как tmpfs (тип RAM-диска) для ускорения / tmp и (2) создание файла подкачки для освобождения памяти. Каждый из них разумен сам по себе, но если неосторожный пользователь делает и то, и другое, он устанавливает цикл обмена: когда ОС пытается выгружать страницы, она записывает в tmpfs; это заставляет tmpfs использовать больше памяти; это увеличивает нагрузку на память, вызывая замену большего количества страниц. На моей виртуальной машине это может занять несколько минут, и у вас будет достаточно времени, чтобы увидеть, как система копается в яме top.

Закрытие программы не имеет большого значения, так как сама программа почти не выделяет памяти. Действительно, освободить память не так просто, поскольку вы не можете освободить память, размонтировав tmpfs перед вашим swapoffфайлом подкачки, и это трудно сделать, пока вы не освободите память.

Этот ответ можно рассматривать как предостерегающую историю против ослепления, применяя прикольные трюки из сети, не понимая их.

sudo mount -t tmpfs -o size=9999G tmpfs /tmp # Use tmpfs to make /tmp faster
truncate -s 4096G /tmp/swap                  # Now make a giant swap file to free up memory 
sudo losetup /dev/loop4 /tmp/swap            # Use a loopback so we can mount the sparse file
sudo mkswap /dev/loop4
sudo swapon /dev/loop4
#The following line would cause a quick swap death, but isn't needed.
#dd if=/dev/zero of=/tmp/zero bs=1          # Zero the tmp dir so the VM can free more memory

2

Perl

sub _ {
  my($f,$b);
  $f=\$b;$b=\$f;
}
while(1) { _;}

Использует циклические ссылки. Счетчик ссылок для переменных никогда не достигнет 0, и ссылки никогда не будут собираться мусором.

Возможно, вам нужно набраться терпения, но это гарантированно душит вашу систему. Диск начнет вращаться быстрее и могут быть видны пары.


2

PHP (только Linux):

Этот код не проверен, так как у меня нет компьютера с Linux, на котором работает php.

Но это мое доказательство концепции:

ignore_user_abort(true);
ini_set('memory_limit',-1);
ini_set('max_execution_time',0);
/*
    sets php to ignore if the script was canceled in the browser
    (like clicking cancel or closing the browser)
    and takes away the memory limit,
    as well as the maximum execution time.
*/

function dont_let_it_stop(){shell_exec('php '.__FILE__.' &');}
//this function calls the file itself.

register_shutdown_function('dont_let_it_stop');
//this function will register the function declared above to be used when the script is being terminated

function get_info($f='current')
{
    return str_replace(' kB','',end(explode(':',trim($f(explode(PHP_EOL,file_get_contents('/proc/meminfo')))))))*1024
}
/*
    this function fetches the infos
    'current' fetches the max memory
    'next' fetches the actual used memory
*/

$max=get_info();//maximum memory
$current=get_info('next');//current memory

$imgs=array(imagecreatetruecolor(1e4,1e4));
$color=imagecolorallocatealpha($imgs[$i=0],128,128,128,126);
imagefill($imgs[$i],0,0,$color);
/*
    this creates an array and inserts one image (10000x10000 pixels),
    filling it then with a solid transparent color
*/

$total-=get_info('next');//calculates the space an image takes

while($max-get_info('next')>$total*2)//while the free memory is higher than the memory of 2 images, fill the array
{
    $imgs[$i++]=imagecreatetruecolor(1e4,1e4);
    $color=imagecolorallocatealpha($imgs[$i-1],128,128,128,126);
    imagefill($imgs[$i-1],0,0,$color);
}

//this is just to keep the images in memory, so the script doesn't end
while(1)sleep(60);

Это заполнит память огромными изображениями RGBA (10000x10000 пикселей).

Единственный способ отключить этого ребенка - отключить питание.

Код все прокомментирован.

Любое улучшение, сомнение, ошибка или что-то еще, используйте поле для комментариев ниже.


Кто-нибудь, имеющий доступ к Linux, может протестировать его? Спасибо :)
Джордж

У меня есть Linux, я просто не уверен, как это будет работать. Я предоставил экран печати для первого ответа, но это действительно старая версия Puppy Linux. Ubuntu слишком медленный для запуска php. Возможно, я протестирую на своем Android позже.
Исмаэль Мигель

1
не в состоянии не вызывать другую программу
Einacio

Он не вызывает другую программу: он вызывает ту же программу, которая запустила файл для того же файла.
Исмаэль Мигель

2

Python - 56

class x:
 def __setattr__(self,*args):self.y=0
x().y=0

Создает класс, определяет метод для установки атрибутов, устанавливает в нем атрибут и создает начальный экземпляр, для которого он затем пытается установить атрибут.

Простая рекурсивная функция ( def f(x):f(x)) казалась немного невообразимой, поэтому я решил никогда не вызывать функцию.

Управление памятью может улавливать глубину рекурсии, но это действительно зависит от реализации.

Если это вилочная бомба, пожалуйста, скажите мне.


4
Это не приводит к истощению памяти, просто: RuntimeError: maximum recursion depth exceeded while calling a Python object. Даже установка максимального предела рекурсии sys.setrecursionlimitбез использования памяти используется до того, как произойдет сбой из-за ошибки сегментации.
Бакуриу

@Bakuriu Как я уже сказал, это действительно зависит от реализации (есть реализации Python, которые конвертируются в C (++) и компилируются, например, Shedskin, Nuitka).
cjfaure

2
Затем укажите, для какой конкретной реализации вы пишете код. Существует разница между проблемами, когда важен только синтаксис и, следовательно, реализация, и задачами, которые полностью зависят от того, как реализован язык.
Бакуриу

2

Perl

Это просто, но я чувствовал, что играю в гольф.

{$x=[$x];redo}

После двух итераций $xсодержит ссылку на массив, содержащий ссылку на массив, содержащий undef.

Использование памяти линейно во времени, с небольшими распределениями, но потребовалось всего несколько секунд, чтобы сильно замедлить мой оконный менеджер в моей системе Ubuntu Linux. Через полминуты об этом позаботился убийца ООМ.


2

ECMAScript 6:

z=z=>{while(1)z()};_=i=>(i+=1,i-=1,i++,i--,--i,++i,i<<=2,i>>=2,i+=0|Math.round(1+Math.random())&1|0,z(x=>setInterval(x=>z(x=>new Worker('data:text/javascript,'+_.toSource()),5))));setInterval(x=>z(x=>_(...Array(9e3).map((x,z)=>z*3/2*2/4*4e2>>2<<2))),5)

Ungolfed:

function forever(code) {
    // Loop forever
    var counter = 0;

    while (counter++ < 10) setInterval(code, 5);
};

function main(counter) {
    // Do some work.
    counter += 1; counter -= 1;

    counter++; counter--;
    --counter; ++counter;

    counter <<= 2;
    counter >>= 2;

    counter += 0 | Math.round(1 + Math.random()) & 1 | 0;

    forever(() => {
        setInterval(() => {
            forever(() => new Worker('data:text/javascript,' + main.toString()));
        }, 5);
    });
};

setInterval(() => {
    forever(() => {
        main(...Array(9e3).map((currentValue, index) => index * 3 / 2 * 2 / 4 * 4e2 >> 2 << 2));
    });
}, 5);

Примечание: он использует setTimeout, который определяется как часть таймеров - HTML Living Standard .

Попробуйте это на Mozilla Firefox (вы можете вставить его в консоль разработчика). Firefox продолжает поглощать все больше и больше памяти и использует100% процессор на одноядерном компьютере (на 4-ядерном компьютере, таком как мой, он использует 25%процессор). Это также имеет дополнительное преимущество, что вы не можете остановить его; если вы можете открыть диспетчер задач, вы можете убить Firefox с его помощью.


1
Он использует 100% ядра. На вашем четырехъядерном процессоре это приводит к 25% использования процессора.
Иван Перес

@Electrosa Да, вы абсолютно правы. Я обновил свой ответ.
Зубная щетка

Это не вопрос гольф-кода, пожалуйста, постарайтесь сделать ваш код читабельным.
Пауло Эберманн

@ PaŭloEbermann ОК. Я выложил неоправданную версию.
Зубная щетка

1

удар

Создать пустой файл test
Заменить /dev/null/этим текстовым файлом

$ sudo mv test /dev/null

Это работает аналогично ответу @ Comintern. Все выходные данные /dev/nullтеперь будут добавлены в этот текстовый файл, который со временем станет огромным и приведет к краху системы.


1
Огромный файл не сломал бы систему. При условии, что средний размер диска составляет 500 ГБ, потребуется много времени, чтобы файл даже приблизился к заполнению диска.
w4etwetewtwet

1
В системах, где /devесть devtmpfs, он может заполнить и помешать системе. Я предполагаю, что цель этого ответа.
Тоби Спейт

1

Баш: 7 символов

Это должно быть самое простое решение для bash. Нет вилок, нет обмана.

x=`yes`

Вам не рекомендуется запускать это как root.


Дополнительное примечание: даже если вы завершите это с помощью Ctrl-C на полпути, а затем unsetпеременной, память останется выделенной, пока оболочка не будет уничтожена. Вы можете посмотреть бойню top.
Бунт

Мои собственные тесты с bash 4.2.45 (1) показывают, что unset xосвобождает память. pdksh также освобождает память, но ksh93 не может освободить ее, а exitв ksh93 сбрасывает ядро.
Kernigh

Для меня (bash 4.3.11 (1)) отображение резидентной памяти в верхней части родительской оболочки неуклонно поднимается до тех пор, пока не yesбудет уничтожено, и в этот момент он просто остается там, не unsetимея никакого эффекта. Но это в большой системе памяти, и наличие переменной, которая составляет несколько гигабайт, похоже, не беспокоит ее (пока она, наконец, не решит убить оболочку).
Бунт

0

С

main()
{
    void * buffer;
    while (1)
        buffer = malloc(4096);
}

Ну, это занимает память страницу за страницей и, наконец, не осталось памяти.


Насколько универсальна страница размером 4 КБ?
Питер Мортенсен

@Peter 4K часто имеет размер, но я не могу сказать, действительно ли он универсальный, но размер страницы не имеет отношения к данному вопросу.
ST3

1
@ ST3: Вы должны сделать страницу памяти грязной. Большинство современных операционных систем используют виртуальную память и просто делают запись в таблице виртуальной памяти, когда вы выделяете память. Запись одного байта на страницу памяти уже заставит операционную систему сопоставить страницу виртуальной памяти с физической памятью.
foobar


0

Рубин

a=[];loop{a<<a}

Он просто бесконечно добавляет (рекурсивно!) Самостоятельные ссылки на себя.

Узнал об этом маленьком драгоценном камне, когда кто-то сломал мою песочницу Ruby . : D

Демонстрация рекурсивных аспектов этого:

[1] pry(main)> a=[]; a<<a; a
=> [[...]]
[2] pry(main)> 

0

C ++ 79

void f(char *p,int i){p=new char[i];f(p,++i);}
int main(){char c='a';f(&c,1);}

Non-golfed

void leak(char *p,int i)
{
    p=new char[i];
    leak(p,++i);
}

int main()
{
    char c='a';
    f(&c,1);
}

Я исправил свою запись, чтобы включить звонок с главной.


Это конкурс популярности. Если программа работает, оставьте ее основной и заголовок. это отлично. Кроме того, не могли бы вы опубликовать версию не для гольфа? Спасибо :)
Джордж
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.