Buat kebocoran memori, tanpa bom garpu [ditutup]


54

Tugas Anda adalah membuat kebocoran memori . Ini adalah program yang menggunakan banyak memori, sampai komputer habis dan harus melakukan beberapa swapping untuk menyelamatkan diri dari kehabisan. Satu-satunya cara agar memori dapat dilepaskan adalah dengan mematikan program di task manager atau menggunakan command line kill seperti taskkill /im yourprogram /f(di Windows) atau bahkan me-restart komputer. Hanya menutup aplikasi seharusnya tidak mencegahnya melanjutkan ke memori babi.

Aturan:

  1. Bom Fork dalam bentuk apa pun dilarang. Itu berarti bahwa garis Bash yang terkenal :(){ :|:&};:dilarang!

  2. Aplikasi harus single-threaded saja. Ini menyiratkan aturan bom garpu.

  3. Program tidak boleh menjalankan program lain. Ini berarti Anda tidak dapat melakukan sesuatu seperti run(memoryfiller.exe). Satu-satunya pengecualian untuk ini adalah program yang dibundel dengan OS atau bahasa Anda, yang pada dasarnya tidak dirancang untuk menggunakan memori (yaitu mereka memiliki tujuan lain). Ini berarti bahwa hal-hal seperti catdan ln -sdiizinkan.

  4. Anda dapat mengambil memori sebanyak yang Anda suka. Lebih banyak lebih baik.

  5. Kode harus dijelaskan sepenuhnya.

Semoga berhasil. Ini adalah kontes popularitas sehingga kode dengan suara terbanyak setelah 10 hari dari tanggal yang diminta menang!


8
"Menutupnya harus tetap menjadikannya memori hog" - jika suatu program adalah shell executable (seperti kebanyakan versi windows dari bahasa scripting interprestor), menutup jendelanya akan mematikan program.
mniip

54
Bukankah ini adil while(1)malloc(999);?
Gagang pintu

10
Saya tidak yakin apakah "Menutupnya masih harus membuatnya menjadi memori babi" kompatibel dengan "Aplikasi harus berurutan tunggal saja." Jika tidak ada utas yang memiliki sebagian memori, OS dapat mengembalikannya, bukan?
aebabis

51
Jalankan saja firefox 26 dengan beberapa tab buka menjalankan flash selama setengah jam. Ini akan membuat komputer Anda bertekuk lutut.
Braden Best

1
@niip. Itulah inti tantangannya. Untuk membuat tantangan yang sulit. Dan gagang pintu. Saya menginginkan sesuatu yang berbeda! ;)
George

Jawaban:


78

Windows

Win32 API memungkinkan Anda untuk mengalokasikan memori dalam proses lain, dan kemudian membaca / menulis memori itu dari jarak jauh. Program ini hanya memiliki satu utas, yang digunakan untuk menghitung setiap proses yang berjalan pada sistem, dan kemudian berulang kali mengalokasikan 1MB buffer dalam setiap proses hingga alokasi gagal. Ketika selesai dengan satu proses, ia beralih ke proses berikutnya. Alokasi tidak dirilis ketika program panggilan selesai - hanya ketika / jika setiap proses target selesai. Ini menggantung 2GB Windows 7 VM dalam waktu sekitar 10 detik. Itu memang membutuhkan menjalankan sebagai admin.

Untuk mengkompilasi: 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 itu jahat.
tommeding

4
Saya harus tutup malam ini. Aku akan mencobanya;)
George

1
"(berjalan sebagai pengguna normal, tidak menggunakan hak admin" - tidak yakin tentang ini, Anda perlu SeDebugPrivilege yang secara default tidak ada dalam token pengguna biasa
rkosegi

@rkosegi Terima kasih, sudah diperbaiki.
Andrew Medico

14
+1 Ini layak mendapatkan banyak upvotes karena sejauh ini adalah satu - satunya jawaban yang memenuhi yang asli. Menutupnya harus tetap menjadikannya kebutuhan memori . Solusi yang sangat kreatif :-)
Daniel

72

Jawa

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();
    } 
  }
}

Penjelasan

Anda mungkin berasumsi bahwa karena tidak ada referensi dalam kode (selain count, yang dapat Anda abaikan dengan aman), itu tidak dapat bocor. Namun, finalizer menciptakan dua Hydra baru, dan sementara itu tidak memiliki referensi untuk ini, mereka akan bertahan sampai selesai. Ini berarti bahwa program hanya membocorkan memori selama pengumpulan sampah - karenanya panggilan ke System.gc()dan System.runFinalization().


7
@TIM. dimana tuhanmu sekarang?!?
Cruncher

Apakah System.gc()dan System.runFinalization()perlu? Yaitu apakah gc akan berjalan secara acak kadang-kadang, atau apakah Anda harus mengisi memori, atau memanggil gc?
Cruncher

4
Dalam program yang khas, System.gc()dan System.runFinalization()tidak perlu. Pengumpulan sampah akan terjadi secara alami karena tekanan memori. Namun dalam aplikasi ini tidak ada tekanan memori sampai pengumpulan sampah mulai berjalan. Saya berpikir tentang secara artifisial memperkenalkan beberapa (misalnya, dengan bergerak new Hydra()di dalam lingkaran), tetapi berpikir ini lebih jahat.
James_pic

1
Ya, saya tidak terlalu memperhatikan "Menutup itu harus tetap menjadikannya memori hog" peringatan, karena tampaknya tidak bermakna (terlepas dari peretasan OS yang rapi seperti @ german_guy's). Java selalu memutar utas finalisasi, jadi mungkin tidak ada cara bagi aplikasi Java untuk mematuhi aturan # 2.
James_pic

1
Pada sistem Unix, Anda tidak dapat memblokir SIGKILL (sinyal 9), jadi Anda tidak dapat membuat program Anda tidak terhentikan (yah, kecuali jika Anda berhasil membuatnya dalam keadaan menunggu tanpa gangguan ... jadi mungkin membunuh jauh server NFS yang file-file Anda akses mungkin bekerja ;-))
celtschk

37

C

Menggunakan bahasa pemrograman C dan diuji dengan kernel Linux 2.6.32-49-generic dan libc-2.11.1.so.

Satu-satunya cara agar memori dapat dilepaskan adalah dengan mematikan program di task manager atau menggunakan taskkill / im yourprogram / f atau bahkan me-restart PC.

Ini dicapai dengan memblokir sinyal apa pun kecuali untuk SIGKILL dan SIGSTOP.

Menutupnya masih harus membuatnya jadi ingatan.

Ini benar-benar membingungkan saya ... Membunuh atau menutup keduanya menghasilkan penghentian proses, memungkinkan sistem operasi untuk mengklaim kembali memori yang dialokasikan oleh proses. Tapi kemudian saya harus berpikir bahwa dengan menutupnya Anda mungkin bermaksud menutup terminal atau proses induk lainnya yang mengeksekusi proses kebocoran memori. Jika saya benar, maka saya memecahkan masalah ini dengan memblokir sinyal apa pun, yang mengubah proses menjadi daemon ketika proses induk dihentikan. Dengan begitu Anda dapat menutup terminal yang sedang menjalankan proses dan akan terus berjalan dan melanjutkan ke kebocoran memori.

Bom Fork dalam bentuk apa pun dilarang. Itu berarti bahwa bash terkenal: () {: |: &} ;: dilarang!

Prosesnya tidak bercabang.

Aplikasi harus satu utas saja. Ini menyiratkan aturan bom garpu

Tidak ada utas baru yang muncul.

Program tidak boleh menjalankan program lain. Ini berarti Anda tidak bisa melakukan sesuatu seperti menjalankan (memoryfiller.exe)

Tidak ada proses baru yang muncul.

Anda dapat mengambil memori sebanyak yang Anda suka. Lebih banyak lebih baik.

Sebanyak sistem operasi dapat menyediakan.

Kode harus dijelaskan sepenuhnya.

Menambahkan komentar ke sumbernya.

Dan akhirnya inilah kodenya:

#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;
}

Bagi siapa saja yang tertarik dengan apa yang terjadi jika Anda menjalankan program ini: Pada sistem pengujian saya dengan 2GB RAM dan ruang swap 4GB, dibutuhkan sekitar 10 menit untuk mengisi RAM dan swap. Pembunuh OOM mulai bekerja dan tiga menit kemudian jenis semua proses telah terbunuh. Bahkan mouse, keyboard, dan display telah dijatuhkan oleh sistem. /var/log/kern.log tidak menunjukkan informasi yang berguna, kecuali untuk proses yang telah terbunuh.


Saya mengedit sumber untuk membuat oom killer mengabaikan proses dan membunuh proses yang tidak bersalah untuk membebaskan memori.
foobar

5
Bagi siapa saja yang tertarik dengan apa yang terjadi jika Anda menjalankan program ini: Pada sistem pengujian saya dengan 2GB RAM dan ruang swap 4GB, dibutuhkan sekitar 10 menit untuk mengisi RAM dan swap. Pembunuh OOM mulai bekerja dan tiga menit kemudian jenis semua proses telah terbunuh. Bahkan mouse, keyboard, dan display telah dijatuhkan oleh sistem. /var/log/kern.log tidak menunjukkan informasi yang berguna, kecuali untuk proses yang telah terbunuh.
foobar

Haha, itu luar biasa! Anda harus mengedit deskripsi itu menjadi jawaban Anda. +1
Gagang Pintu

1
Saya tidak downvote, tapi alangkah baiknya jika kode tersebut dapat diformat sehingga tidak diperlukan pengguliran horizontal untuk membaca komentar.
Paŭlo Ebermann

2
+1 untuk 1) menyebabkan proses menyerahkan perangkat input / output terbunuh dan 2) membuat program yang sulit dilacak dari log. Ini adalah tingkat kejahatan kumis yang mengeriting.
Kevin - Reinstate Monica

29

Bash murni

Bukan bom fork, saya berjanji:

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

Itu mirip sekali dengan bom fork, dan menggunakan teknik rekursif yang serupa, tetapi tidak menggunakan fork. Tentu saja ini akan membuat shell Anda kehabisan memori, jadi Anda disarankan untuk memulai shell baru sebelum menempelkan perintah ini.

  • Tentukan fungsi yang disebut :
  • Fungsi ini hanya menyebut dirinya secara rekursif dengan $@(daftar arg) dua kali lipat
  • Setelah definisi fungsi, :fungsi dipanggil dengan argumen awal:

Keluaran:

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

Dalam edit sebelumnya dari jawaban ini yang saya lakukan a=$(yes), tetapi saya perhatikan aturan "Program tidak boleh menjalankan program lain", jadi saya perlu menggunakan murni bashalih-alih tanpa memanggil coreutils atau apa pun.


Ini satu lagi:

TOLONG JANGAN RUN INI PADA MESIN PRODUKSI

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

Sekali lagi, ini bukan bom fork - semuanya dijalankan dari dalam satu utas. Yang ini tampaknya cukup mudah membuat VM Ubuntu saya bertekuk lutut, dengan sedikit ruang untuk pemulihan, selain reboot.

Seperti pada bom fork klasik, fungsi rekursif :()didefinisikan. Namun itu tidak menutup panggilan untuk dirinya sendiri. Sebaliknya ia menyebut dirinya dengan satu argumen, yang dengan sendirinya disebut dalam proses substitusi . Karena penggantian proses berfungsi dengan membuka deskriptor file /dev/fd/n, ini tidak hanya memakan memori proses (bash), itu juga akan memakan sebagian memori kernel juga. Di mesin Ubuntu saya ini memiliki efek membuat window manager tidak dapat dioperasikan setelah beberapa detik, kemudian tak lama setelah berakhir dengan layar ini:

masukkan deskripsi gambar di sini

Mengklik OKlalu memberikan layar ini:

masukkan deskripsi gambar di sini

Tak satu pun dari opsi ini tampaknya sangat membantu - pada saat ini memulai kembali tampaknya menjadi satu-satunya pilihan yang baik.


3
$ which yes->/usr/bin/yes
Izkata

2
"Satu-satunya cara agar memori dapat dilepaskan adalah dengan mematikan program di task manager atau menggunakan taskkill / im yourprogram / f atau bahkan me-restart PC. Menutupnya masih harus membuatnya menjadi memori babi." >> Bash dapat diakhiri dengan menggunakan SIGTERM, jadi membunuh itu tidak diperlukan untuk membuatnya berhenti berjalan. Itu juga berhenti berjalan ketika sistem kehabisan memori. Setelah bash diakhiri, baik oleh SIGTERM atau dengan kehabisan memori, memori diberikan kembali ke sistem operasi.
foobar

Ini tidak berfungsi untuk saya ... semacam ... Saya dapat melihat memori secara bertahap hilang, tetapi ini terjadi sangat lambat, dan itu juga dapat dibunuh hanya dengan menekan ctrl + c. Ini berjalan sekarang selama 1 menit dan ditempati sekitar 1GB. Saya punya mesin yang SANGAT cepat ... tapi itu tidak masalah, kan?
Stefanos Kalantzis

Membalas komentar saya sendiri: Perintah ini benar-benar membunuh bash setelah sekitar 2 menit 49sec. Saya awalnya berasumsi itu akan instan berdasarkan jawaban ini.
Stefanos Kalantzis

@StefanosKalantzis Terima kasih atas komentar Anda. Itu membuat saya berpikir sedikit lebih dan saya baru saja menemukan potongan shell yang lebih jahat - lihat edit.
Trauma Digital

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;"/>

Kemudian meneruskan dokumen ke parser XML yang tidak melakukan loop referensi entitas / deteksi rekursi. Misalnya, xpathdisertakan dengan perl:

xpath boom.xml /

Bagaimana itu bekerja:

  1. Pengurai bertemu <boom a="&a;">
  2. Parser mengembang "&a;"menjadi"&b;&b;"
  3. Parser memperluas salah satu ke "&b;"dalam "&c;&c;"(kembali, itu akan memperluas yang lain "&b;")
  4. Parser memperluas salah satu dari "&c;"...

Jika ekspansi penuh dapat terjadi, akan ada ekspansi 2 ^ 52 "ka-boom!". Dengan asumsi 2-byte per karakter, ia akan mencoba menggunakan 64 PiB. Ekspansi berjalan "ka-boom!" pada suatu waktu, jadi Anda biasanya dapat menontonnya menggunakan semua memori di atas.

Ini berjalan dengan berbagai nama, ikhtisar yang baik di sini: http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion


3
Pada dasarnya, salinan Billion laughs
Cole Johnson

@ColeJohnson Yup, itu dia! Saya berkontribusi pada proyek Klasifikasi Ancaman WASC, jadi saya merasa berkewajiban untuk menunjuk ke WASC daripada Wikipedia. :)
ɲeuroburɳ

22

C ++

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

Kode ini tidak terduga! Itu tergantung komputer saya ketika task manager terbuka dan menunjukkan bahwa dibutuhkan 890 Mb memori dalam 1 detik kemudian juga tergantung. Saya tidak tahu bagaimana ini bekerja, mungkin itu terus memberikan memori ke variabel. Untuk mengeksplorasi lebih lanjut dari kode ini saya menambahkan pernyataan delete a;dan semuanya baik-baik saja saat pengujian (tidak tergantung) Jadi, saya pikir potongan memori adalah diberikan (karena new int) dan kemudian dibawa kembali (karena delete a) ke ruang kosong dalam kode baru di bawah ini.

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

Jadi, saya menyimpulkan bahwa TIDAK ADA RAM DI DUNIA INI DAPAT MENANGANI KODE INI !!!

EDIT : Tetapi banyak prosesor dapat misalnya intel core 2 duotidak dapat menangani kode ini tetapi
intel core i-seriesbisa (bekerja untuk saya ...)

Ingat jawaban untuk pertanyaan adalah kode 1, yang kedua adalah untuk penjelasan.


9
Bagus, kompiler berpikir Anda masih akan menggunakan new intmeskipun Anda menimpa pointer, sehingga Anda tidak pernah dapat mengaksesnya lagi ... Jadi tidak ada pengumpulan sampah yang dipanggil dan Anda mengisi memori lebih cepat daripada anak gemuk makan skittles
David Wilkins

37
@ DavidWilkins: ... ini adalah C ++, C ++ tidak memiliki pengumpul sampah.
Phoshi

32
Jika tidak terduga bagi Anda bahwa kode ini bocor, maka saya pikir Anda tidak boleh menggunakan C ++ sampai Anda mempelajarinya dengan lebih baik.
svick

1
@vick Tapi tidak seperti memukul papan panah dalam gelap! Saya punya beberapa Ide bahwa ini akan melakukan pertanyaan pekerjaan yang diinginkan.
Mukul Kumar

15
@vick Bagaimana dia bisa 'belajar lebih baik' jika dia 'tidak boleh menggunakan C ++'?
Kevin

16

BrainFuck

+[>+]

Penjelasan:

Untuk memasukkan loop, ia meningkatkan sel menjadi 1. Ia bergerak ke sel berikutnya meningkatkan itu menjadi 1 selama sel terakhir positif.

Biasanya interpreter BrainFuck cacat karena memiliki batasan yang keras terhadap jumlah sel dalam rekaman itu, tetapi beberapa penafsir menambahkan sel secara dinamis. Ini akan terus mengkonsumsi memori hingga tidak lagi dikonsumsi.

beefadalah salah satu juru bahasa seperti itu dan tersedia di Pusat Perangkat Lunak Ubuntu dan proses saya saat ini pada mesin yang tidak digunakan mulai 29 jam yang lalu dan telah mengkonsumsi 1GB RAM pada waktu itu. Inilah output daritop

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

Ini memiliki 4GB cache dan 6GB swap jadi saya kira saya akan memperbarui jawaban ini dengan bagaimana dalam 12 hari.

PEMBARUAN 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    

PEMBARUAN 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   

Jadi sudah berjalan selama 10 hari. Sepertinya itu akan berjalan setidaknya 10 lebih sebelum sesuatu yang menarik terjadi.


Bagus dan pendek.
nrubin29

15

C dan POSIX

Di sini saya bertujuan untuk solusi yang sangat portabel. Masalahnya adalah bahwa C murni tampaknya tidak memiliki cara untuk memberitahu Sistem Operasi bahwa memori harus tetap dialokasikan setelah program ditutup. Jadi saya membiarkan diri saya menggunakan POSIX; sebagian besar OS memiliki klaim kompatibilitas POSIX termasuk Windows, Linux dan MacOS X. Namun, saya hanya mengujinya di Ubuntu 12.04 32bit. Itu tidak memerlukan izin pengguna super.

Solusi ini pada dasarnya adalah while(1){malloc(1);}solusi tradisional . Namun alih-alih malloc, ia menggunakan fungsi memori bersama POSIX. Karena ia menetapkan pengenal memori bersama untuk setiap alokasi, masih mungkin untuk mengakses memori setelah proses berakhir. Dengan demikian kernel tidak dapat membebaskan memori.

#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*/
  }
}

IMO jawaban C terbaik dan paling cemerlang. +1
syb0rg

1
Bagus Solusi pertama yang saya temukan adalah Andrew Medico, tetapi karena itu tidak mungkin di Linux dan karena saya tidak suka pemrograman Windows, saya ingin membocorkan melalui memori bersama, tetapi tidak dapat mengingat nama fungsi POSIX. Terima kasih telah mengingat saya tentang mereka;) Yang saya temukan hanyalah hal-hal mmap yang belum dipetakan pada proses penghentian ...
foobar

14

C #

Lupa berhenti berlangganan dari peristiwa sebelum pawang keluar dari ruang lingkup akan menyebabkan .NET bocor memori sampai melempar 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;
    }
}

Penjelasan : Di dalam whileloop, kami membangun objek baru, menyebabkan kerangka kerja mengalokasikan lebih banyak memori, tetapi kami juga mencegah instance baru Bagar tidak dilepaskan ketika keluar dari ruang lingkup dengan menetapkan metode instance ke acara di kelas yang berbeda, hasilnya adalah bahwa instance baru Btidak dapat dijangkau dari kode kami, tetapi referensi masih ada, artinya GC tidak akan merilisnya sampai ajuga keluar dari ruang lingkup.

Acara statis memiliki jebakan yang sama, karena mereka tidak pernah keluar dari ruang lingkup, mereka hanya dibersihkan ketika proses berakhir, kecuali jika Anda berhenti berlangganan dari acara tersebut terlebih dahulu. Selalu simpan referensi Anda, orang-orang!

using System;

class Program
{
    static event Action Event;

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

Di atas bekerja pada ide yang sama, pawang menjadi tidak dapat dijangkau setelah whileloop keluar dari ruang lingkup, sehingga tidak mungkin untuk berhenti berlangganan dari acara tersebut, yang berarti memori akan duduk di sana sampai program berakhir. Peristiwa statis bisa dibilang lebih berbahaya daripada peristiwa instan, karena Anda dapat memastikan mereka tidak pernah keluar dari ruang lingkup.

EDIT : Anda juga dapat melakukan hal yang sama dengan objek lain pada dasarnya, asalkan Anda menambahkan referensi sementara pada saat yang sama memastikan tidak ada cara untuk membebaskan referensi itu.

Berikut ini contoh yang menggunakan objek dan array statis.

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 );
    }
}

Array terus ditambahkan ke daftar, tetapi tidak ada cara untuk menghapus daftar tanpa mengubah kode, yang tidak mungkin untuk aplikasi sumber tertutup. Meningkatkan jumlah yang diteruskan Leak.Addakan menyebabkannya bocor lebih cepat, jika Anda mengaturnya cukup tinggi itu hanya akan mengakibatkan langsung OverflowException dilemparkan.


10

bash (tidak ada utilitas eksternal)

Tidak ada bom garpu di sini.

Peringatan: Mungkin membunuh cangkang Anda.

Hanya mencoba membuat array bilangan bulat untuk referensi karena saya terus lupa bagaimana bilangan bulat terlihat.

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

Hasil dalam:

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

2
+1 untuk "karena saya selalu lupa bagaimana bilangan bulat terlihat" :)
David Conrad

8

J (7)

PERINGATAN: Ini membekukan sistem saya ketika saya mencobanya (Windows 8, J 8.01, di terminal qt).

2#^:_[_
  • 2# menggandakan panjang argumen dengan menduplikasi setiap elemen,
  • ^:_ menemukan fixpoint dari fungsi yang diberikan (tetapi tidak ada satu sehingga loop tanpa henti),
  • [_menyebutnya dengan _argumen.

8

Haskell (nomor Graham)

Ini sangat sederhana: ini menghitung nomor Graham

Tidak seperti contoh lain di sini, itu tidak akan berjalan selamanya ... itu akan menggunakan banyak CPU, tetapi secara teoritis itu bisa berakhir. kalau bukan karena fakta bahwa untuk menyimpan nomor ...

alam semesta yang teramati terlalu kecil untuk mengandung representasi digital biasa dari nomor Graham, dengan asumsi bahwa setiap digit menempati satu volume Planck .

(menurut wikipedia)

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

Jadi, idenya adalah bahwa memori akan digunakan oleh (serangkaian semakin) sangat besar Integer(bilangan bulat Haskell adalah ukuran sewenang-wenang).

Jika Anda ingin mengujinya, Anda mungkin harus menambah ukuran tumpukan atau memuatnya di dalam ghci.


2
Alam semesta bodoh, tidak sesuai dengan standar Haskell untuk Integer. Mengapa itu tidak dapat mendukung ukuran sewenang-wenang?
PyRulez

6

Terinspirasi oleh @comintern.

Mengganti / dev / null. Terlibat dalam mode licik. Membutuhkan header kernel, mode superuser dan kompiler yang berfungsi.

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

Selamat bersenang-senang.

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

Kode sumber:

#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);

Peringatan ini mungkin memaksa Anda untuk reboot!

Untuk menghapusnya:

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

6

Rubi

Semua orang tahu jumlah itu (1 / n ^ 2) = pi ^ 2/6

Jadi saya bisa mendefinisikan fungsi aproksimasi:

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

p pi_approx.(100_000)

Tentu saja (1..infinity) akan berjalan liar.

Namun perhatikan bahwa menggunakan malas akan membuat ini berhasil;)

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 karakter (program lengkap)

Jangan jalankan yang itu, atau sistem Anda akan dengan cepat menjadi beku!

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

Panggilan ke malloc akan menyimpan 9 byte memori dan meminta halaman memori baru dari sistem operasi secara teratur. Memori yang dialokasikan oleh malloc segera bocor karena tidak ada pointer ke alamat yang dikembalikan disimpan. Setelah sistem kehabisan memori (RAM dan ruang swap) atau batas memori untuk proses tercapai, program akan keluar dari while-loop dan berakhir.


2
Tidak lama - sistem modern mana pun yang layak harus memiliki pembunuh OOM yang menendang dan membunuh prosesnya. Setidaknya Ubuntu 12.04 tidak.
Digital Trauma

1
Yah, saya crash Ubuntu 13.10 saya saat mencoba kode ini ...
Mathieu Rodic

@DigitalTrauma Apakah mis. FreeBSD punya OOMK?
Ruslan

1
main(){while(malloc(9));}menyimpan 3 karakter lainnya, dan mengisi ingatan saya cukup banyak secara instan.
gmatht

@ gmatht: terima kasih atas sarannya! Saya mengedit jawabannya ... meskipun saya menyukai gagasan untuk meningkatkan ukuran blok pada setiap loop.
Mathieu Rodic

4

VBScript

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

Kami membuat kamus yang menunjuk ke dirinya sendiri. Kemudian kami berpikir bahwa kami menghancurkan kamus dengan mengaturnya ke Nothing. Namun, kamus masih ada dalam memori karena memiliki referensi (lingkaran) yang valid.

Loop, tetapi juga babi memori, menyebabkan program untuk hang. Setelah mematikan program, memori masih digunakan. Sistem hanya dapat dikembalikan dengan menyalakannya kembali.


Uh benarkah? VBScript tidak hanya menggunakan VB.NET di bawah tenda? Referensi lingkaran biasanya bukan masalah bagi pemulung, kecuali untuk implementasi penghitungan referensi sederhana, dan penghentian program harus menghasilkan pelepasan seluruh tumpukannya, bukan?
David Conrad

@ Davidvidon Anda akan berpikir begitu, tapi saya harus me-restart mesin saya setiap kali saya menyelidiki ini dan menjalankan skrip jenis ini.
AutomatedChaos

1
VBScript mendahului VB.Net secara signifikan - ini bukan versi baris perintah dari VB.Net; ini adalah bagian yang diinterpretasikan dari warisan Visual Basic.
Chris J

Terima kasih, kalian berdua. Saya tidak menyadari apa hubungan antara VBScript dan VB.NET.
David Conrad

4

Ya & tmpfs

Mengapa menulis program baru ketika ada yang gratis dengan Ubuntu?

yes > /run/user/$UID/large_file_on_my_ramdisk

Seperti yang mungkin Anda ketahui, atau sudah ditebak, Ubuntu mount / run / user / secara default sebagai tmpfs yang merupakan jenis disk RAM .

Anda bahkan tidak perlu menutupnya. Itu akan dengan sopan menutup sendiri, meninggalkan sepotong memori yang dialokasikan. Saya kira yesadalah program single-threaded, proses tunggal yang tidak memanggil yang lain (menulis ke disk RAM yang ada juga mudah dibawa-bawa untuk bahasa pilihan Anda).

Ini memiliki bug kecil: Ubuntu membatasi tmpfs / run / 1000 hingga 100 MB yang dapat ditulisi pengguna, jadi fitur swap kematian mungkin tidak didukung pada mesin Anda di luar kotak. Namun saya berhasil memperbaikinya pada mesin saya dengan solusi cepat berikut:

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

Saya tidak punya /run/userdirektori sama sekali. Versi Ubuntu apa yang Anda gunakan dan apa yang Anda instal untuk ini?
Ruslan

Ubuntu Trusty Tahr (14.04). Tidak diperlukan pemasangan khusus.
gmatht

Untuk mengetahui apakah Anda memiliki tmpfssistem file yang terpasang, Anda dapat mendaftarnya df -t tmpfs. Sistem Ubuntu saya memiliki banyak sekali /run/shm...
Toby Speight

4

Pesta

Peringatan: Kode berikut akan membuat komputer Anda tidak bisa di-boot.

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

Peringatan: Kode sebelumnya akan membuat komputer Anda tidak bisa di-boot.

Ganti / dev / hda dengan boot drive Anda. Ini menulis E8 FD FF pada awal sektor boot Anda. Saat boot, BIOS membaca sektor boot Anda ke dalam memori dan menjalankannya. Opcode tersebut setara dengan rakitan ini:

label:
  call label

Ini adalah rekursi tak terbatas, yang pada akhirnya akan menyebabkan stack overflow.


Dalam contoh Majelis Anda, Anda dapat menyimpan karakter (dengan asumsi nama "label" diperlukan) dengan menggunakan jmpalih - alihcall
SirPython

panggilan meninggalkan alamat pengirim di stack untuk ret. lompatan tidak akan menyebabkan stack overflow.
Jerry Jeremiah

3

Haskell

main=print $ sum [0..]

Ini mencoba untuk menambah jumlah penghitungan. Haskell tidak mengevaluasi jumlah parsial, itu hanya menjadi pernyataan tambahan yang tak terbatas. Jika Anda menjalankan kompiler dengan flag optimasi, itu mungkin tidak berfungsi sekalipun.


3

Pesta

Karena kita dapat menggunakan utilitas yang tidak secara khusus dirancang untuk mengkonsumsi memori, saya fokus pada utilitas untuk membebaskan memori: swapon. Ini digunakan untuk memungkinkan kernel membebaskan memori dengan menulis ke disk.

Script ini melakukan dua optimasi: (1) Mounting tmp sebagai tmpfs (sejenis disk RAM) untuk membuat / tmp lebih cepat dan (2) membuat swapfile untuk membebaskan memori. Masing-masing masuk akal sendiri tetapi jika pengguna yang ceroboh melakukan keduanya maka ia mengatur siklus pertukaran: ketika OS mencoba untuk menukar halaman, itu menulis ke tmpfs; ini membuat tmpfs menggunakan lebih banyak memori; ini meningkatkan tekanan memori yang menyebabkan lebih banyak halaman ditukar. Ini bisa memakan waktu beberapa menit pada VM saya, banyak waktu bagi Anda untuk menonton sistem menggali dirinya sendiri menggunakan lubang top.

Menutup program membuat sedikit perbedaan karena program itu sendiri hampir tidak mengalokasikan memori apa pun. Memang tidak mudah untuk membebaskan memori karena Anda tidak dapat membebaskan memori dengan melepas tmpfs sebelum Anda swapoffswapfile, dan itu sulit dilakukan sampai Anda membebaskan memori.

Jawaban ini dapat dianggap sebagai dongeng peringatan untuk membutakan penerapan trik keren dari internet tanpa memahaminya.

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) { _;}

Menggunakan referensi melingkar. Jumlah referensi untuk variabel tidak akan pernah mencapai 0, dan referensi tidak akan pernah menjadi sampah yang dikumpulkan.

Anda mungkin perlu bersabar, tetapi dijamin mencekik sistem Anda. Disk akan mulai berputar lebih cepat dan asap mungkin terlihat.


2

PHP (hanya linux):

Kode ini belum diuji, karena saya tidak punya komputer linux dengan php yang berjalan.

Tapi ini adalah bukti konsep saya:

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);

Ini akan mengisi memori dengan gambar RGBA besar (10000x10000 piksel).

Satu-satunya cara untuk mematikan bayi ini adalah mematikan daya.

Kode semua komentar.

Setiap perbaikan, keraguan, bug, atau apa pun, gunakan kotak komentar di bawah ini.


Adakah yang punya akses ke pikiran linux yang mengujinya? Terima kasih :)
George

Saya memiliki linux, saya hanya tidak yakin bagaimana cara kerjanya. Saya memberikan printscreen untuk jawaban pertama, tetapi itu adalah versi yang sangat lama dari puppy linux. Ubuntu terlalu lambat untuk menjalankan php. Mungkin saya menguji di Android saya nanti.
Ismael Miguel

1
itu gagal tentang tidak memanggil program lain
Einacio

Itu tidak memanggil program lain: itu memanggil program yang sama yang memulai file untuk file yang sama.
Ismael Miguel

2

Python - 56

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

Membuat kelas, mendefinisikan metode untuk mengatur atribut, menetapkan atribut di dalamnya, dan membuat contoh awal yang kemudian mencoba untuk mengatur atribut.

Fungsi rekursif sederhana ( def f(x):f(x)) tampak agak tidak imajinatif jadi saya memutuskan untuk tidak pernah benar-benar memanggil fungsi.

Manajemen memori mungkin menangkap kedalaman rekursi, tetapi itu benar-benar tergantung pada implementasinya.

Jika ini bom fork, tolong beri tahu saya.


4
Hal ini menyebabkan tidak ada kelelahan memori, hanya: RuntimeError: maximum recursion depth exceeded while calling a Python object. Bahkan pengaturan batas rekursi maksimum dengan sys.setrecursionlimithampir tidak ada memori digunakan sebelum crash dengan kesalahan segmentasi.
Bakuriu

@ Bakuriu Seperti yang saya katakan, itu benar-benar tergantung pada implementasi (ada implementasi Python yang dikonversi ke C (++) dan kompilasi, misalnya Shedskin, Nuitka).
cjfaure

2
Kemudian nyatakan implementasi tertentu yang Anda tuliskan kode tersebut. Ada perbedaan antara tantangan di mana hanya masalah sintaksis dan dengan demikian implementasinya tidak relevan, dan tantangan yang sepenuhnya bergantung pada bagaimana bahasa diimplementasikan.
Bakuriu

2

Perl

Ini sederhana, tapi saya ingin bermain golf.

{$x=[$x];redo}

Setelah dua iterasi, $xberisi referensi ke array yang berisi referensi ke array yang mengandung undef.

Penggunaan memori linear dalam waktu, dengan alokasi yang kecil, tetapi hanya butuh beberapa detik untuk memperlambat window manager saya di sistem Ubuntu Linux saya. Setengah menit kemudian si pembunuh OOM membereskannya.


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)

Tidak Disatukan:

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);

Catatan: Ini digunakan setTimeout, yang didefinisikan sebagai bagian dari Pengatur Waktu - Standar Hidup HTML .

Cobalah di Mozilla Firefox (Anda dapat menempelkannya di konsol pengembang). Firefox terus memakan lebih banyak memori, dan penggunaan 100%CPU pada mesin single-core (pada mesin 4-core, seperti milik saya, itu menggunakan 25%CPU). Ini juga memiliki manfaat tambahan yang tidak dapat Anda hentikan; jika Anda dapat membuka task manager, Anda dapat mematikan Firefox dengan itu.


1
Ia menggunakan 100% inti. Pada prosesor quadcore Anda, yang menghasilkan 25% dari penggunaan CPU.
Iván Pérez

@ Electra Ya, Anda benar sekali. Saya telah memperbarui jawaban saya.
Sikat gigi

Ini bukan pertanyaan kode golf, coba buat kode Anda dapat dibaca.
Paŭlo Ebermann

@ PaŭloEbermann OK. Saya telah memposting versi yang tidak diklik.
Sikat gigi

1

Pesta

Buat file kosong test
Ganti /dev/null/dengan file teks ini

$ sudo mv test /dev/null

Ini bekerja dengan cara yang mirip dengan jawaban @ Comintern. Semua output untuk /dev/nullsekarang akan ditambahkan ke file teks ini, yang seiring waktu akan menjadi besar dan merusak sistem.


1
File besar tidak akan merusak sistem. Dan dengan asumsi ukuran disk rata-rata 500GB akan memakan waktu lama untuk file bahkan mendekati mengisi disk.
w4etwetewtwet

1
Pada sistem di mana /deva devtmpfs, itu dapat mengisi dan menghalangi sistem. Saya menduga itulah maksud dari jawaban ini.
Toby Speight

1

Bash: 7 karakter

Ini harus menjadi solusi bash paling sederhana. Tanpa garpu, tidak ada kecurangan.

x=`yes`

Anda disarankan untuk tidak menjalankan ini sebagai root.


Catatan tambahan: bahkan jika Anda menghentikan ini dengan ctrl-c di tengah jalan, dan kemudian unsetvariabel, memori tetap dialokasikan sampai shell terbunuh. Anda dapat menonton pembantaian di top.
Kerusuhan

Tes saya sendiri dengan bash 4.2.45 (1) menunjukkan bahwa unset xtidak membebaskan memori. pdksh juga membebaskan memori, tetapi ksh93 gagal membebaskannya, dan exitdi ksh93 membuang inti.
kernigh

Bagi saya (bash 4.3.11 (1)), tampilan memori penduduk di atas untuk shell induk naik dengan mantap sampai yesterbunuh, pada titik mana itu hanya tinggal di sana, unsettidak memiliki efek. Tapi ini pada sistem memori yang besar dan memiliki variabel yang beberapa gigabytes tampaknya tidak menyusahkannya (sampai akhirnya memutuskan untuk membunuh shell).
Kerusuhan

0

C

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

Yah dibutuhkan memori halaman demi halaman dan akhirnya tidak ada memori yang tersisa.


Seberapa universal halaman menjadi 4 KB?
Peter Mortensen

@ Peter 4K sering berukuran, tapi saya tidak tahu apakah itu benar-benar universal, tetapi ukuran halaman tidak memiliki hubungan dengan pertanyaan yang diberikan.
ST3

1
@ ST3: Anda harus membuat halaman memori kotor. Sebagian besar sistem operasi modern menggunakan memori virtual dan hanya membuat catatan di tabel memori virtual, ketika Anda mengalokasikan memori. Menulis satu byte ke halaman memori sudah akan memaksa sistem operasi untuk memetakan halaman memori virtual ke memori fisik.
foobar


0

Rubi

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

Itu hanya tanpa henti menambahkan referensi diri (rekursif!) Untuk dirinya sendiri.

Mengetahui tentang permata kecil ini ketika seseorang memecah kotak pasir Ruby saya dengannya . : D

Demo aspek rekursifnya:

[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-golf

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

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

Saya memperbaiki entri saya untuk memasukkan panggilan dari utama.


Ini adalah kontes popularitas. Jika program berfungsi, simpan bagian utama dan tajuknya. tidak apa-apa. Juga, bisakah Anda memposting versi yang tidak golf? Terima kasih :)
George
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.