如何一條命令,榨干機器的所有內(nèi)存?
最近在驗證一些機器的內(nèi)存分配規(guī)律的時候,學習到了一些技能,趁著周末有時候?qū)扅c東西,跟大家分享一下。
大家可能有遇到類似的場景,想要對機器進行壓測模擬 OOM 的場景,但是無奈機器的規(guī)格實在太高,若用代碼去實現(xiàn),大家可以想象一下如何實現(xiàn)?個人感覺還是有點麻煩的。
那么有沒有好有的辦法,不用寫代碼,用幾個簡單的命令直接就可以向機器申請內(nèi)存呢?或者更極端點,直接把機器的內(nèi)存給榨干了。。
若你經(jīng)常使用 linux,你會發(fā)現(xiàn) df -Th 后,一定會有 tmpfs 類型的文件系統(tǒng)掛載在 /dev/shm 下面,雖然你大概率不會關(guān)注到它。
- $ df -Th
- Filesystem Type Size Used Avail Use% Mounted on
- devtmpfs devtmpfs 910M 0 910M 0% /dev
- tmpfs tmpfs 919M 0 919M 0% /dev/shm
- tmpfs tmpfs 919M 896K 918M 1% /run
- tmpfs tmpfs 919M 0 919M 0% /sys/fs/cgroup
- /dev/vda1 ext4 40G 11G 27G 28% /
- tmpfs tmpfs 184M 0 184M 0% /run/user/0
而這個 tmpfs 就是明哥今天要介紹的主角。
tmpfs,顧名思義,是臨時文件系統(tǒng),是一種基于內(nèi)存的文件系統(tǒng)。
它和虛擬磁盤 ramdisk比較類似像,但不完全相同,和ramdisk一樣,tmpfs可以使用RAM,但它也可以使用swap分區(qū)來存儲,而且傳統(tǒng)的ramdisk是個塊設備,要用mkfs來格式化它,才能真正地使用它;而tmpfs是一個文件系統(tǒng),并不是塊設備,只是安裝它,就可以使用了。tmpfs是最好的基于RAM的文件系統(tǒng)。
這意味著,你往掛載了 tmpfs 的目錄下寫入的文件,都會直接寫入內(nèi)存中。
假如你想占用機器 10G 的內(nèi)存,那我只要先創(chuàng)建一個臨時目錄 /tmp/memory ,并指定 tmpfs 的文件系統(tǒng)類型及大小 10240M 掛載到該目錄下。
- $ mount -t tmpfs -o size=10240M tmpfs /tmp/memory
接著咱使用 dd 命令,往該目錄下寫入多少內(nèi)容,就會占用多少內(nèi)存,由于我們的目的是占用內(nèi)存,因此 if 直接使用 /dev/zero
- $ dd if=/dev/zero of=/tmp/memory/block
當 dd 寫入完成后,你再使用 free 去查看可用內(nèi)存,會發(fā)現(xiàn)剩余的內(nèi)存可分配的內(nèi)存少了 10G。
如果你想用完機器的所有內(nèi)存,完全可以在 mount 的時候,指定 size 為機器的內(nèi)存大小,但你要清楚你在做什么,否則執(zhí)行完 dd ,你的機器可能就掛了。
利用上面這個方法,其實還可以做更多的事情,比如你在機器你有兩個 NUMA Node ,但你只想占用 NUMA Node 0 的內(nèi)存,那就可以指定 NUMA Node 0 的內(nèi)存,怎么辦呢?
首先利用 lscpu 找到 NUMA Node 0 上的所有 cpu 核
- $ node0_cpus=$(lscpu | grep "NUMA node0" | awk '{print $NF}')
然后使用 taskset 工具加 -c 參數(shù)來指定對應的 cpu 核來執(zhí)行創(chuàng)建 tmpfs 目錄和 dd 的過程
- $ cat > /root/mem_alloc.sh <<EOF
- #!/bin/bash
- tmpdir=`mktemp`
- mount -t tmpfs -o size=1024M tmpfs ${tmpdir}
- dd if=/dev/zero of=${tmpdir}/block
- EOF
- $ taskset -c "${node0_cpus}" sh /root/mem_alloc.sh
執(zhí)行完成后,如果你所占用的內(nèi)存,沒有超過 NUMA Node 0 的本地內(nèi)存,那么你使用 numactl 就會發(fā)現(xiàn)上面命令都只占用了 NUMA Node0 的內(nèi)存。
這么簡單,你學會了嗎?