Saya ingin melakukan beberapa pengujian sumber daya rendah dan untuk itu saya perlu memiliki 90% dari memori bebas penuh.
Bagaimana saya bisa melakukan ini pada *nix
sistem?
Saya ingin melakukan beberapa pengujian sumber daya rendah dan untuk itu saya perlu memiliki 90% dari memori bebas penuh.
Bagaimana saya bisa melakukan ini pada *nix
sistem?
Jawaban:
stress-ng adalah generator beban kerja yang mensimulasikan tekanan cpu / mem / io / hdd pada sistem POSIX. Panggilan ini harus melakukan trik di Linux <3.14:
stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Untuk Linux> = 3.14, Anda dapat menggunakan MemAvailable
untuk memperkirakan memori yang tersedia untuk proses baru tanpa bertukar:
stress-ng --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Sesuaikan /proc/meminfo
panggilan dengan free(1)
/ vm_stat(1)
/ etc. jika Anda membutuhkannya portabel.
stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' < /proc/meminfo)k --vm-keep -m 1
--vm 1 and --vm-keep
sangat penting. Cukup --vm-bytes
tidak melakukan apa-apa dan Anda mungkin disangka berpikir Anda dapat mengalokasikan memori sebanyak yang Anda butuhkan / inginkan. Saya mendapatkan sedikit dengan ini sampai saya mencoba untuk memeriksa kewarasan diriku dengan mengalokasikan 256G memori. Ini bukan cacat dalam jawabannya, itu memberikan bendera yang benar, hanya peringatan tambahan.
-m 1
. Menurut halaman stres, -m N
adalah kependekan dari --vm N
: N
pekerja spawn berputar terusmalloc()/free()
Anda dapat menulis program C ke malloc()
memori yang diperlukan dan kemudian menggunakannya mlock()
untuk mencegah memori tidak ditukar.
Kemudian biarkan program menunggu input keyboard, dan membuka kunci memori, membebaskan memori dan keluar.
calloc
akan mengalami masalah IIRC yang sama. Semua memori hanya akan mengarah ke halaman nol-baca yang sama. Ini tidak akan benar-benar dialokasikan sampai Anda mencoba menulis ke sana (yang tidak akan berfungsi karena hanya baca). Satu-satunya cara untuk benar-benar yakin bahwa saya tahu adalah dengan melakukan memset
seluruh buffer. Lihat jawaban berikut untuk info lebih lanjut stackoverflow.com/a/2688522/713554
Saya akan menyarankan menjalankan VM dengan memori terbatas dan menguji perangkat lunak yang akan menjadi tes yang lebih efisien daripada mencoba mengisi memori pada mesin host.
Metode itu juga memiliki keuntungan bahwa jika situasi memori rendah menyebabkan kesalahan OOM di tempat lain dan menggantung seluruh OS, Anda hanya menggantung VM yang Anda uji di mesin Anda dan Anda mungkin memiliki proses berguna lainnya berjalan.
Juga jika pengujian Anda bukan CPU atau IO intensif, Anda dapat secara bersamaan menjalankan contoh pengujian pada keluarga VM dengan berbagai ukuran memori rendah.
Dari komentar HN ini: https://news.ycombinator.com/item?id=6695581
Cukup isi / dev / shm melalui dd atau serupa.
swapoff -a dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k
pv
diinstal, ada baiknya untuk melihat hitungan:dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024
Jika Anda memiliki alat GNU dasar ( sh
, grep
, yes
dan head
) Anda dapat melakukan ini:
yes | tr \\n x | head -c $BYTES | grep n
# Protip: use `head -c $((1024*1024*2))` to calculate 2MB easily
Ini berfungsi karena grep memuat seluruh baris data dalam RAM (saya mempelajari ini dengan cara yang agak disayangkan ketika grepping gambar disk). Garis, yang dihasilkan oleh yes
, menggantikan baris baru, akan panjang tak terhingga, tetapi dibatasi oleh head
ke $BYTES
byte, sehingga grep akan memuat $ BYTES dalam memori. Grep sendiri menggunakan seperti 100-200KB untuk saya, Anda mungkin perlu mengurangi itu untuk jumlah yang lebih tepat.
Jika Anda juga ingin menambahkan batasan waktu, ini dapat dilakukan dengan mudah di bash
(tidak akan berfungsi sh
):
cat <(yes | tr \\n x | head -c $BYTES) <(sleep $NumberOfSeconds) | grep n
The <(command)
hal tampaknya sedikit diketahui tetapi sering sangat berguna, info lebih lanjut tentang di sini: http://tldp.org/LDP/abs/html/process-sub.html
Kemudian untuk penggunaan cat
: cat
akan menunggu input selesai sampai keluar, dan dengan menjaga salah satu pipa terbuka, itu akan membuat grep tetap hidup.
Jika Anda telah pv
dan ingin secara perlahan meningkatkan penggunaan RAM:
yes | tr \\n x | head -c $BYTES | pv -L $BYTESPERSEC | grep n
Sebagai contoh:
yes | tr \\n x | head -c $((1024*1024*1024)) | pv -L $((1024*1024)) | grep n
Akan menggunakan hingga satu gigabyte dengan kecepatan 1MB per detik. Sebagai bonus tambahan, pv
akan menunjukkan tingkat penggunaan saat ini dan total penggunaan sejauh ini. Tentu ini juga bisa dilakukan dengan varian sebelumnya:
yes | tr \\n x | head -c $BYTES | pv | grep n
Hanya memasukkan | pv |
bagian akan menunjukkan kepada Anda status saat ini (throughput dan total, secara default, saya pikir - kalau tidak lihat halaman man (ual)).
Mengapa ada jawaban lain? Jawaban yang diterima merekomendasikan untuk menginstal paket (saya yakin ada rilis untuk setiap chipset tanpa memerlukan manajer paket); jawaban pilihan teratas merekomendasikan kompilasi program C (saya tidak memiliki kompiler atau toolchain yang diinstal untuk dikompilasi untuk platform target Anda); jawaban pilihan kedua teratas merekomendasikan untuk menjalankan aplikasi dalam VM (ya biarkan aku hanya dd sdcard internal ponsel ini melalui usb atau sesuatu dan membuat gambar virtualbox); yang ketiga menyarankan untuk memodifikasi sesuatu dalam urutan boot yang tidak mengisi RAM seperti yang diinginkan; yang keempat hanya berfungsi sejauh / dev / shm mountpoint (1) ada dan (2) besar (remounting membutuhkan root); yang kelima menggabungkan banyak hal di atas tanpa kode sampel; keenam adalah jawaban yang bagus tetapi saya tidak melihat jawaban ini sebelum datang dengan pendekatan saya sendiri, jadi saya pikir saya akan menambahkan sendiri, juga karena itu lebih pendek untuk diingat atau ketik jika Anda tidak melihat bahwa garis memblob sebenarnya adalah inti dari masalah ini; ketujuh lagi tidak menjawab pertanyaan (menggunakan ulimit untuk membatasi proses sebagai gantinya); yang kedelapan mencoba membuat Anda menginstal python; yang kesembilan berpikir kita semua sangat tidak kreatif dan akhirnya yang kesepuluh menulis program C ++ sendiri yang menyebabkan masalah yang sama dengan jawaban pilihan teratas.
set -e
, jadi saya baru belajar sesuatu :)
time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n
(gunakan memori 10 GiB) membutuhkan waktu 1 menit 46 detik. Menjalankan program eatmemory julman99 di github.com/julman99/eatmemory membutuhkan waktu 6 detik. ... Ya, ditambah waktu unduh dan kompilasi, tetapi dikompilasi tanpa masalah ... dan sangat cepat ... di mesin RHEL6.4 saya. Tetap saja, saya suka solusi ini. Mengapa menemukan kembali roda?
Saya menjaga fungsi untuk melakukan sesuatu yang serupa di dotfiles saya. https://github.com/sagotsky/.dotfiles/blob/master/.functions#L248
function malloc() {
if [[ $# -eq 0 || $1 -eq '-h' || $1 -lt 0 ]] ; then
echo -e "usage: malloc N\n\nAllocate N mb, wait, then release it."
else
N=$(free -m | grep Mem: | awk '{print int($2/10)}')
if [[ $N -gt $1 ]] ;then
N=$1
fi
sh -c "MEMBLOB=\$(dd if=/dev/urandom bs=1MB count=$N) ; sleep 1"
fi
}
Bagaimana abount solusi python sederhana?
#!/usr/bin/env python
import sys
import time
if len(sys.argv) != 2:
print "usage: fillmem <number-of-megabytes>"
sys.exit()
count = int(sys.argv[1])
megabyte = (0,) * (1024 * 1024 / 8)
data = megabyte * count
while True:
time.sleep(1)
sysctl vm.swappiness=0
dan selanjutnya mengatur vm.min_free_kbytes ke sejumlah kecil, mungkin 1024. Saya belum mencobanya, tetapi para dokter mengatakan bahwa ini adalah bagaimana Anda mengontrol kecepatan bertukar ... Anda harus mampu membuatnya sangat lambat, sampai menyebabkan kondisi OOM pada mesin Anda. Lihat kernel.org/doc/Documentation/sysctl/vm.txt dan kernel.org/doc/gorman/html/understand/understand005.html
Bagaimana dengan ramf jika ada? Pasang dan salin ke file besar? Jika tidak ada /dev/shm
dan tidak ada ramf - saya kira program C kecil yang melakukan malloc besar berdasarkan pada beberapa nilai input? Mungkin harus menjalankannya beberapa kali sekaligus pada sistem 32 bit dengan banyak memori.
Jika Anda ingin menguji proses tertentu dengan memori terbatas, Anda mungkin lebih baik menggunakan ulimit
untuk membatasi jumlah memori yang dapat dialokasikan.
man setrlimit
:RLIMIT_RSS Specifies the limit (in pages) of the process's resident set (the number of virtual pages resident in RAM). This limit only has effect in Linux 2.4.x, x < 30, and there only affects calls to madvise(2) specifying MADV_WILLNEED.
Saya pikir ini adalah kasus mengajukan pertanyaan yang salah dan kewarasan ditenggelamkan oleh orang-orang yang bersaing untuk mendapatkan jawaban paling kreatif. Jika Anda hanya perlu mensimulasikan kondisi OOM, Anda tidak perlu mengisi memori. Cukup gunakan pengalokasi khusus dan gagal setelah sejumlah alokasi tertentu. Pendekatan ini tampaknya bekerja cukup baik untuk SQLite .
Saya menulis program C ++ kecil ini untuk itu: https://github.com/rmetzger/dynamic-ballooner
Keuntungan dari implementasi ini adalah secara berkala memeriksa apakah perlu membebaskan atau mengalokasikan kembali memori.