ฉันต้องการทำการทดสอบที่มีทรัพยากรต่ำและฉันจำเป็นต้องมีหน่วยความจำว่าง 90% ที่เต็ม
ฉันจะทำสิ่งนี้บน*nix
ระบบได้อย่างไร?
ฉันต้องการทำการทดสอบที่มีทรัพยากรต่ำและฉันจำเป็นต้องมีหน่วยความจำว่าง 90% ที่เต็ม
ฉันจะทำสิ่งนี้บน*nix
ระบบได้อย่างไร?
คำตอบ:
stress-ngเป็นตัวสร้างเวิร์กโหลดที่จำลอง cpu / mem / io / hdd stress บนระบบ POSIX การโทรนี้ควรทำเคล็ดลับบน Linux <3.14:
stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
สำหรับ Linux> = 3.14 คุณสามารถใช้MemAvailable
แทนการประมาณหน่วยความจำที่มีอยู่สำหรับกระบวนการใหม่โดยไม่ต้องสลับ:
stress-ng --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
ปรับ/proc/meminfo
สายด้วยfree(1)
/ vm_stat(1)
/ ฯลฯ หากคุณต้องการพกพา
stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' < /proc/meminfo)k --vm-keep -m 1
--vm 1 and --vm-keep
มีความสำคัญ เพียงแค่--vm-bytes
ไม่ทำอะไรเลยและคุณอาจจะหลงคิดว่าคุณสามารถจัดสรรหน่วยความจำมากที่สุดเท่าที่คุณต้องการ / ความต้องการของคุณ ฉันได้รับบิตนี้จนกว่าฉันจะพยายามตรวจสอบตัวเองด้วยการจัดสรรหน่วยความจำ 256G นี่ไม่ใช่ข้อบกพร่องในคำตอบมันให้ค่าสถานะที่ถูกต้องเพียงแค่ระมัดระวังเพิ่มเติม
-m 1
นี่คือเหตุผลที่มี ตาม manpage ความเครียด-m N
สั้นสำหรับ--vm N
: วางไข่N
คนงานปั่นบนmalloc()/free()
คุณสามารถเขียนโปรแกรม C ไปmalloc()
ยังหน่วยความจำที่ต้องการจากนั้นใช้mlock()
เพื่อป้องกันไม่ให้หน่วยความจำถูกสลับ
จากนั้นให้โปรแกรมรออินพุตคีย์บอร์ดและปลดล็อกหน่วยความจำเพิ่มหน่วยความจำและออก
calloc
จะพบปัญหาเดียวกัน IIRC หน่วยความจำทั้งหมดจะชี้ไปที่หน้าศูนย์อ่านอย่างเดียวที่เหมือนกัน มันจะไม่ได้รับการจัดสรรจนกว่าคุณจะพยายามเขียนลงไป (ซึ่งจะไม่ทำงานเนื่องจากเป็นแบบอ่านอย่างเดียว) วิธีเดียวที่จะแน่ใจว่าฉันรู้จริง ๆ คือการทำmemset
บัฟเฟอร์ทั้งหมด ดูคำตอบต่อไปนี้สำหรับข้อมูลเพิ่มเติมstackoverflow.com/a/2688522/713554
ฉันขอแนะนำให้ใช้ VM กับหน่วยความจำที่ จำกัด และทดสอบซอฟต์แวร์ซึ่งจะเป็นการทดสอบที่มีประสิทธิภาพมากกว่าการพยายามเติมหน่วยความจำบนเครื่องโฮสต์
วิธีการดังกล่าวยังมีข้อได้เปรียบว่าหากสถานการณ์หน่วยความจำเหลือน้อยทำให้เกิดข้อผิดพลาดของ OOM ที่อื่นและแฮงค์ทั้งระบบคุณเพียงวาง VM ที่คุณกำลังทดสอบในเครื่องของคุณที่คุณอาจมีกระบวนการที่มีประโยชน์อื่น ๆ
นอกจากนี้หากการทดสอบของคุณไม่ใช่ CPU หรือ IO มากคุณสามารถรันอินสแตนซ์ของการทดสอบในตระกูลของ VM พร้อมกับขนาดหน่วยความจำต่ำหลากหลายในเวลาเดียวกัน
จากความคิดเห็น HN นี้: https://news.ycombinator.com/item?id=6695581
เพียงแค่กรอก / dev / shm ผ่าน dd หรือคล้ายกัน
swapoff -a dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k
pv
ติดตั้งแล้วจะช่วยให้เห็นจำนวน:dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024
mem=nn[KMG]
พารามิเตอร์ boot kernel(ดูรายละเอียดใน linux / Documentation / kernel-parameters.txt)
ถ้าคุณมีเครื่องมือ GNU พื้นฐาน ( sh
, grep
, yes
และhead
) ที่คุณสามารถทำเช่นนี้:
yes | tr \\n x | head -c $BYTES | grep n
# Protip: use `head -c $((1024*1024*2))` to calculate 2MB easily
สิ่งนี้ทำงานได้เนื่องจาก grep โหลดข้อมูลทั้งหมดใน RAM (ฉันได้เรียนรู้สิ่งนี้ในทางที่ค่อนข้างโชคร้ายเมื่อทำการ grepping ดิสก์อิมเมจ) บรรทัดที่สร้างโดยyes
, การขึ้นบรรทัดใหม่เปลี่ยนจะมีความยาวเพียบ แต่ถูก จำกัด ด้วยhead
การ$BYTES
ไบต์จึง grep จะโหลด $ ไบต์ในหน่วยความจำ Grep ใช้ตัวเองเช่น 100-200KB สำหรับฉันคุณอาจต้องลบมันออกเพื่อให้ได้ปริมาณที่แม่นยำยิ่งขึ้น
หากคุณต้องการเพิ่มการ จำกัด เวลาก็สามารถทำได้อย่างง่ายดายในbash
(จะไม่ทำงานsh
):
cat <(yes | tr \\n x | head -c $BYTES) <(sleep $NumberOfSeconds) | grep n
<(command)
สิ่งที่ดูเหมือนจะเป็นที่รู้จักกันเล็ก ๆ น้อย ๆ แต่บ่อยครั้งที่เป็นประโยชน์อย่างยิ่งข้อมูลเพิ่มเติมเกี่ยวกับมันที่นี่: http://tldp.org/LDP/abs/html/process-sub.html
จากนั้นสำหรับการใช้cat
: cat
จะรอให้อินพุตดำเนินการจนจบและโดยการเปิดท่อใดท่อหนึ่งก็จะทำให้ grep ยังมีชีวิตอยู่
หากคุณมีpv
และต้องการเพิ่มการใช้ RAM อย่างช้าๆ:
yes | tr \\n x | head -c $BYTES | pv -L $BYTESPERSEC | grep n
ตัวอย่างเช่น:
yes | tr \\n x | head -c $((1024*1024*1024)) | pv -L $((1024*1024)) | grep n
จะใช้มากถึงกิกะไบต์ในอัตรา 1MB ต่อวินาที เป็นโบนัสเพิ่มเติมpv
จะแสดงอัตราการใช้ปัจจุบันและการใช้ทั้งหมดจนถึงปัจจุบัน แน่นอนว่าสิ่งนี้สามารถทำได้กับตัวแปรรุ่นก่อนหน้า:
yes | tr \\n x | head -c $BYTES | pv | grep n
เพียงแค่การแทรก| pv |
ส่วนจะแสดงสถานะปัจจุบัน (ปริมาณงานและยอดรวมตามค่าเริ่มต้นฉันคิดว่า - ไม่เช่นนั้นจะเห็นหน้า man (ual))
ทำไมต้องมีคำตอบอื่นอีก? คำตอบที่ได้รับการยอมรับแนะนำให้ติดตั้งแพคเกจ (ฉันพนันได้เลยว่าจะมีการเปิดตัวชิปเซ็ตทุกชุดโดยไม่จำเป็นต้องมีผู้จัดการแพ็คเกจ) คำตอบที่ได้รับคะแนนสูงสุดแนะนำให้รวบรวมโปรแกรม C (ฉันไม่ได้ติดตั้งคอมไพเลอร์หรือ Toolchain เพื่อรวบรวมสำหรับแพลตฟอร์มเป้าหมายของคุณ); คำตอบที่ได้รับการโหวตอันดับสองแนะนำให้รันแอปพลิเคชั่นใน VM (ใช่แล้วขอให้ฉันใช้ sdcard ภายในของโทรศัพท์นี้ผ่าน usb หรืออะไรซักอย่างแล้วสร้างภาพ virtualbox); ที่สามแนะนำการแก้ไขบางสิ่งบางอย่างในลำดับการบู๊ตที่ไม่เติม RAM ตามที่ต้องการ ส่วนที่สี่ใช้งานได้เฉพาะในจุดที่ / dev / shm mountpoint (1) มีอยู่และ (2) มีขนาดใหญ่ (จำเป็นต้องมีการรูทใหม่) ที่ห้ารวมหลายอย่างโดยไม่มีรหัสตัวอย่าง; คำตอบที่หกเป็นคำตอบที่ดี แต่ฉันไม่เห็นคำตอบนี้ก่อนที่จะเข้าหาวิธีการของตัวเอง ดังนั้นฉันคิดว่าฉันจะเพิ่มของตัวเองเพราะมันสั้นกว่าที่จะจำหรือพิมพ์ทับหากคุณไม่เห็นว่าบรรทัด memblob นั้นเป็นประเด็นสำคัญของเรื่องนี้ ที่เจ็ดอีกครั้งไม่ตอบคำถาม (ใช้ ulimit เพื่อ จำกัด กระบวนการแทน); ที่แปดพยายามให้คุณติดตั้งหลาม; เก้าคิดว่าเราทุกคนไม่สร้างสรรค์มากและในที่สุดสิบก็เขียนโปรแกรม C ++ ของเขาเองซึ่งทำให้เกิดปัญหาเดียวกันกับคำตอบที่ได้รับการโหวตสูงสุด
set -e
ดังนั้นฉันเพิ่งได้เรียนรู้บางสิ่งบางอย่าง :)
time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n
(ใช้หน่วยความจำ 10 GiB) ใช้เวลา 1 นาที 46 วินาที ใช้งานโปรแกรม eatmemory ของ julman99 ที่github.com/julman99/eatmemoryใช้เวลา 6 วินาที ... รวมทั้งเวลาในการดาวน์โหลดและรวบรวม แต่มันรวบรวมโดยไม่มีปัญหา ... และเร็วมาก ... บนเครื่อง RHEL6.4 ของฉัน ยังฉันชอบวิธีนี้ ทำไมต้องคิดค้นล้อใหม่
ฉันใช้ฟังก์ชันทำสิ่งที่คล้ายกันในดอทไฟล์ของฉัน 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
}
วิธีลดความซับซ้อนของโซลูชันหลามอย่างง่าย ๆ ?
#!/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
และตั้งค่า vm.min_free_kbytes เป็นจำนวนน้อยอาจจะ 1024 ฉันยังไม่ได้ลอง แต่ doc บอกว่านี่เป็นวิธีที่คุณควบคุมความรวดเร็วในการแลกเปลี่ยน ... คุณควรจะ สามารถทำให้มันค่อนข้างช้าไปจนถึงจุดที่ทำให้เกิดสภาวะ OOM บนเครื่องของคุณ ดูkernel.org/doc/Documentation/sysctl/vm.txtและkernel.org/doc/gorman/html/understand/understand005.html
ramfs ถ้ามันมีอยู่แล้วล่ะ? ติดตั้งและคัดลอกไฟล์ขนาดใหญ่หรือไม่ หาก/dev/shm
ไม่มี ramfs ไม่และ - ฉันเดาโปรแกรม C เล็ก ๆ ที่ทำ malloc ขนาดใหญ่ตามค่าอินพุตบางอย่าง? อาจต้องเรียกใช้สองสามครั้งในระบบ 32 บิตพร้อมหน่วยความจำจำนวนมาก
หากคุณต้องการทดสอบกระบวนการเฉพาะกับหน่วยความจำที่ จำกัด คุณอาจจะดีกว่าที่จะใช้ulimit
เพื่อ จำกัด จำนวนหน่วยความจำที่จัดสรรได้
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.
ฉันคิดว่านี่เป็นกรณีของการถามคำถามที่ไม่ถูกต้องและความมีน้ำใจของผู้คนที่แข่งขันกันเพื่อหาคำตอบที่สร้างสรรค์ที่สุด หากคุณต้องการจำลองสถานการณ์ OOM เท่านั้นคุณไม่จำเป็นต้องเติมหน่วยความจำ เพียงใช้ตัวจัดสรรแบบกำหนดเองและทำให้มันล้มเหลวหลังจากมีการจัดสรรจำนวนหนึ่ง วิธีนี้ดูเหมือนว่าจะทำงานได้ดีพอสำหรับSQLite
ฉันเขียนโปรแกรม C ++ ตัวน้อยสำหรับสิ่งนี้: https://github.com/rmetzger/dynamic-ballooner
ข้อดีของการใช้งานนี้คือการตรวจสอบเป็นระยะ ๆ ว่าจำเป็นต้องเพิ่มหรือจัดสรรหน่วยความจำใหม่