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:
Bom Fork dalam bentuk apa pun dilarang. Itu berarti bahwa garis Bash yang terkenal
:(){ :|:&};:
dilarang!Aplikasi harus single-threaded saja. Ini menyiratkan aturan bom garpu.
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 seperticat
danln -s
diizinkan.Anda dapat mengambil memori sebanyak yang Anda suka. Lebih banyak lebih baik.
Kode harus dijelaskan sepenuhnya.
Semoga berhasil. Ini adalah kontes popularitas sehingga kode dengan suara terbanyak setelah 10 hari dari tanggal yang diminta menang!
sumber
while(1)malloc(999);
?Jawaban:
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
sumber
Jawa
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 keSystem.gc()
danSystem.runFinalization()
.sumber
System.gc()
danSystem.runFinalization()
perlu? Yaitu apakah gc akan berjalan secara acak kadang-kadang, atau apakah Anda harus mengisi memori, atau memanggil gc?System.gc()
danSystem.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 bergeraknew Hydra()
di dalam lingkaran), tetapi berpikir ini lebih jahat.C
Menggunakan bahasa pemrograman C dan diuji dengan kernel Linux 2.6.32-49-generic dan libc-2.11.1.so.
Ini dicapai dengan memblokir sinyal apa pun kecuali untuk SIGKILL dan SIGSTOP.
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.
Prosesnya tidak bercabang.
Tidak ada utas baru yang muncul.
Tidak ada proses baru yang muncul.
Sebanyak sistem operasi dapat menyediakan.
Menambahkan komentar ke sumbernya.
Dan akhirnya inilah kodenya:
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.
sumber
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.
:
$@
(daftar arg) dua kali lipat:
fungsi dipanggil dengan argumen awal:
Keluaran:
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 murnibash
alih-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:Mengklik
OK
lalu memberikan layar ini:Tak satu pun dari opsi ini tampaknya sangat membantu - pada saat ini memulai kembali tampaknya menjadi satu-satunya pilihan yang baik.
sumber
$ which yes
->/usr/bin/yes
XML
Kemudian meneruskan dokumen ke parser XML yang tidak melakukan loop referensi entitas / deteksi rekursi. Misalnya,
xpath
disertakan dengan perl:Bagaimana itu bekerja:
<boom a="&a;">
"&a;"
menjadi"&b;&b;"
"&b;"
dalam"&c;&c;"
(kembali, itu akan memperluas yang lain"&b;"
)"&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
sumber
C ++
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 (karenanew int
) dan kemudian dibawa kembali (karenadelete a
) ke ruang kosong dalam kode baru di bawah ini.Jadi, saya menyimpulkan bahwa TIDAK ADA RAM DI DUNIA INI DAPAT MENANGANI KODE INI !!!
EDIT : Tetapi banyak prosesor dapat misalnya
intel core 2 duo
tidak dapat menangani kode ini tetapiintel core i-series
bisa (bekerja untuk saya ...)Ingat jawaban untuk pertanyaan adalah kode 1, yang kedua adalah untuk penjelasan.
sumber
new int
meskipun 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 skittlesBrainFuck
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.
beef
adalah 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
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
PEMBARUAN 03.31 00:20
Jadi sudah berjalan selama 10 hari. Sepertinya itu akan berjalan setidaknya 10 lebih sebelum sesuatu yang menarik terjadi.
sumber
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.sumber
C #
Lupa berhenti berlangganan dari peristiwa sebelum pawang keluar dari ruang lingkup akan menyebabkan .NET bocor memori sampai melempar OutOfMemoryException.
Penjelasan : Di dalam
while
loop, kami membangun objek baru, menyebabkan kerangka kerja mengalokasikan lebih banyak memori, tetapi kami juga mencegah instance baruB
agar tidak dilepaskan ketika keluar dari ruang lingkup dengan menetapkan metode instance ke acara di kelas yang berbeda, hasilnya adalah bahwa instance baruB
tidak dapat dijangkau dari kode kami, tetapi referensi masih ada, artinya GC tidak akan merilisnya sampaia
juga 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!
Di atas bekerja pada ide yang sama, pawang menjadi tidak dapat dijangkau setelah
while
loop 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.
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.Add
akan menyebabkannya bocor lebih cepat, jika Anda mengaturnya cukup tinggi itu hanya akan mengakibatkan langsung OverflowException dilemparkan.sumber
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.
Hasil dalam:
sumber
J (7)
PERINGATAN: Ini membekukan sistem saya ketika saya mencobanya (Windows 8, J 8.01, di terminal qt).
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.sumber
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 ...
(menurut wikipedia)
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
.sumber
Terinspirasi oleh @comintern.
Mengganti / dev / null. Terlibat dalam mode licik. Membutuhkan header kernel, mode superuser dan kompiler yang berfungsi.
Selamat bersenang-senang.
Makefile:
Kode sumber:
Peringatan ini mungkin memaksa Anda untuk reboot!
Untuk menghapusnya:
sumber
Rubi
Semua orang tahu jumlah itu (1 / n ^ 2) = pi ^ 2/6
Jadi saya bisa mendefinisikan fungsi aproksimasi:
Tentu saja (1..infinity) akan berjalan liar.
Namun perhatikan bahwa menggunakan malas akan membuat ini berhasil;)
sumber
C -
2825 karakter (program lengkap)Jangan jalankan yang itu, atau sistem Anda akan dengan cepat menjadi beku!
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.
sumber
main(){while(malloc(9));}
menyimpan 3 karakter lainnya, dan mengisi ingatan saya cukup banyak secara instan.VBScript
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.
sumber
Ya & tmpfs
Mengapa menulis program baru ketika ada yang gratis dengan Ubuntu?
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
yes
adalah 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:
sumber
/run/user
direktori sama sekali. Versi Ubuntu apa yang Anda gunakan dan apa yang Anda instal untuk ini?tmpfs
sistem file yang terpasang, Anda dapat mendaftarnyadf -t tmpfs
. Sistem Ubuntu saya memiliki banyak sekali/run/shm
...Pesta
Peringatan: Kode berikut akan membuat komputer Anda tidak bisa di-boot.
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:
Ini adalah rekursi tak terbatas, yang pada akhirnya akan menyebabkan stack overflow.
sumber
jmp
alih - alihcall
Haskell
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.
sumber
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
swapoff
swapfile, dan itu sulit dilakukan sampai Anda membebaskan memori.Jawaban ini dapat dianggap sebagai dongeng peringatan untuk membutakan penerapan trik keren dari internet tanpa memahaminya.
sumber
Perl
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.
sumber
PHP (hanya linux):
Kode ini belum diuji, karena saya tidak punya komputer linux dengan php yang berjalan.
Tapi ini adalah bukti konsep saya:
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.
sumber
Python - 56
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.
sumber
RuntimeError: maximum recursion depth exceeded while calling a Python object
. Bahkan pengaturan batas rekursi maksimum dengansys.setrecursionlimit
hampir tidak ada memori digunakan sebelum crash dengan kesalahan segmentasi.Perl
Ini sederhana, tapi saya ingin bermain golf.
Setelah dua iterasi,
$x
berisi referensi ke array yang berisi referensi ke array yang mengandungundef
.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.
sumber
ECMAScript 6:
Tidak Disatukan:
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 menggunakan25%
CPU). Ini juga memiliki manfaat tambahan yang tidak dapat Anda hentikan; jika Anda dapat membuka task manager, Anda dapat mematikan Firefox dengan itu.sumber
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/null
sekarang akan ditambahkan ke file teks ini, yang seiring waktu akan menjadi besar dan merusak sistem.sumber
/dev
adevtmpfs
, itu dapat mengisi dan menghalangi sistem. Saya menduga itulah maksud dari jawaban ini.Bash: 7 karakter
Ini harus menjadi solusi bash paling sederhana. Tanpa garpu, tidak ada kecurangan.
Anda disarankan untuk tidak menjalankan ini sebagai root.
sumber
unset
variabel, memori tetap dialokasikan sampai shell terbunuh. Anda dapat menonton pembantaian ditop
.unset x
tidak membebaskan memori. pdksh juga membebaskan memori, tetapi ksh93 gagal membebaskannya, danexit
di ksh93 membuang inti.yes
terbunuh, pada titik mana itu hanya tinggal di sana,unset
tidak memiliki efek. Tapi ini pada sistem memori yang besar dan memiliki variabel yang beberapa gigabytes tampaknya tidak menyusahkannya (sampai akhirnya memutuskan untuk membunuh shell).C
Yah dibutuhkan memori halaman demi halaman dan akhirnya tidak ada memori yang tersisa.
sumber
Rubi
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:
sumber
C ++ 79
Non-golf
Saya memperbaiki entri saya untuk memasukkan panggilan dari utama.
sumber