Làm thế nào để lấp đầy 90% bộ nhớ trống?


181

Tôi muốn thực hiện một số thử nghiệm tài nguyên thấp và tôi cần phải có 90% bộ nhớ trống.

Làm thế nào tôi có thể làm điều này trên một *nixhệ thống?


3
Nó thực sự phải làm việc trên bất kỳ hệ thống * nix nào?
một CVn

31
Thay vì làm đầy bộ nhớ, bạn có thể tạo một VM (sử dụng docker, hoặc vagrant hoặc một cái gì đó tương tự) có số lượng bộ nhớ hạn chế không?
abendigo

4
@abendigo Đối với QA, nhiều giải pháp được trình bày ở đây rất hữu ích: đối với một hệ điều hành chung không có nền tảng cụ thể, các tham số khởi động VM hoặc kernel có thể hữu ích, nhưng đối với một hệ thống nhúng mà bạn biết đặc tả bộ nhớ của hệ thống được nhắm mục tiêu tôi sẽ đi cho đầy bộ nhớ miễn phí.
Eduard Florinescu

2
Trong trường hợp có ai khác bị sốc một chút bởi cách tính điểm ở đây: meta.unix.stackexchange.com/questions/1513/ .
goldilocks

Câu trả lời:


157

stress-ng là một trình tạo khối lượng công việc mô phỏng ứng suất cpu / mem / io / hdd trên các hệ thống POSIX. Cuộc gọi này sẽ thực hiện thủ thuật trên Linux <3.14:

stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1

Đối với Linux> = 3.14, bạn có thể sử dụng MemAvailablethay thế để ước tính bộ nhớ khả dụng cho các quy trình mới mà không cần trao đổi:

stress-ng --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1

Điều chỉnh /proc/meminfocuộc gọi bằng free(1)/ vm_stat(1)/ etc. nếu bạn cần nó di động.


3
căng thẳng --vm-byte $ (awk '/ MemFree / {printf "% d \ n", $ 2 * 0,097;} </ proc / meminfo) k --vm-giữ -m 10
Robert

1
Hầu hết MemFree được giữ bởi HĐH, vì vậy tôi đã sử dụng MemAv Available thay thế. Điều này đã cho tôi sử dụng 92% trên Cent OS 7.stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' < /proc/meminfo)k --vm-keep -m 1
kujiy

tốt để biết, MemAv Available đã được thêm vào "ước tính dung lượng bộ nhớ khả dụng để bắt đầu các ứng dụng mới, mà không cần trao đổi", xem git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ ...git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/...
tkrennwa

1
Cũng như một ghi chú được thêm vào, cung cấp cả hai --vm 1 and --vm-keepđều rất quan trọng. Đơn giản là --vm-byteskhông làm gì cả và bạn có thể bị lầm tưởng rằng bạn có thể phân bổ bao nhiêu bộ nhớ mà bạn cần / muốn. Tôi đã nhận được một chút bằng cách này cho đến khi tôi cố gắng tự kiểm tra bằng cách phân bổ 256G bộ nhớ. Đây không phải là một lỗ hổng trong câu trả lời, nó cung cấp các cờ chính xác, chỉ là một sự thận trọng bổ sung.
đánh bại

Đây là lý do tại sao có -m 1. Theo trang web căng thẳng, -m Nviết tắt của --vm N: Ncông nhân sinh sản quay vòngmalloc()/free()
tkrennwa

92

Bạn có thể viết chương trình C vào malloc()bộ nhớ cần thiết và sau đó sử dụng mlock()để ngăn bộ nhớ bị tráo đổi.

Sau đó, chỉ cần để chương trình chờ nhập bàn phím và mở khóa bộ nhớ, giải phóng bộ nhớ và thoát.


25
Thời gian dài trở lại tôi đã phải kiểm tra trường hợp sử dụng tương tự. Tôi quan sát thấy rằng cho đến khi bạn viết một cái gì đó vào bộ nhớ đó thì nó sẽ không thực sự được phân bổ (tức là cho đến khi xảy ra lỗi trang). Tôi không chắc liệu mlock () có quan tâm đến điều đó không.
Poorna

2
Tôi đồng tình với @siri; tuy nhiên, nó phụ thuộc vào biến thể UNIX mà bạn đang sử dụng.
Anthony

2
Một số cảm hứng cho mã. Hơn nữa, tôi nghĩ rằng bạn không cần phải mở khóa / giải phóng bộ nhớ . HĐH sẽ làm điều đó cho bạn khi quá trình của bạn kết thúc.
Sebastian

9
Bạn có thể phải thực sự ghi vào bộ nhớ, hạt nhân có thể chỉ quá mức nếu bạn chỉ malloc nó. Nếu được cấu hình, ví dụ Linux sẽ cho phép malloc trở lại thành công mà không thực sự có bộ nhớ và chỉ thực sự phân bổ bộ nhớ khi nó được ghi vào. Xem win.tue.nl/~aeb/linux/lk/lk-9.html
Bjarke Freund-Hansen

7
@Sebastian: callocsẽ gặp vấn đề tương tự IIRC. Tất cả bộ nhớ sẽ chỉ vào cùng một trang zeroed chỉ đọc. Nó sẽ không thực sự được phân bổ cho đến khi bạn cố gắng viết cho nó (nó sẽ không hoạt động vì nó chỉ đọc). Cách duy nhất để thực sự chắc chắn rằng tôi biết là thực hiện một memsetbộ đệm. Xem câu trả lời sau để biết thêm thông tin stackoverflow.com/a/2688522/713554
Leo

45

Tôi khuyên bạn nên chạy VM với bộ nhớ hạn chế và kiểm tra phần mềm trong đó sẽ là một thử nghiệm hiệu quả hơn so với cố gắng lấp đầy bộ nhớ trên máy chủ.

Phương pháp đó cũng có ưu điểm là nếu tình trạng bộ nhớ thấp gây ra lỗi OOM ở nơi khác và treo toàn bộ HĐH, bạn chỉ treo máy ảo mà bạn đang kiểm tra không phải máy của bạn mà bạn có thể có các quy trình hữu ích khác đang chạy.

Ngoài ra, nếu thử nghiệm của bạn không chuyên sâu về CPU hoặc IO, bạn có thể chạy đồng thời các phiên bản thử nghiệm trên một họ máy ảo với nhiều kích cỡ bộ nhớ thấp.


31

Từ HN bình luận này: https://news.ycombinator.com/item?id=6695581

Chỉ cần điền / dev / shm qua dd hoặc tương tự.

swapoff -a
dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k

8
Không phải tất cả * nixes đều có / dev / shm. Bất kỳ ý tưởng di động hơn?
Tadeusz A. Kadłubowski

Nếu pvđược cài đặt, nó sẽ giúp xem số đếm:dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024
Otheus

1
Nếu bạn muốn tốc độ, phương pháp này là lựa chọn đúng đắn! Bởi vì nó phân bổ dung lượng RAM mong muốn trong vài giây. Đừng chuyển tiếp trên / dev / urandom, nó sẽ sử dụng 100% CPU và mất vài phút nếu RAM của bạn lớn. YET, / dev / shm có kích thước tương đối trong các bản phân phối Ubuntu / Debian hiện đại, nó có kích thước mặc định là 50% RAM vật lý. Hy vọng rằng bạn có thể remount / dev / shm hoặc có thể tạo một điểm gắn kết mới. Chỉ cần chắc chắn rằng nó có kích thước thực tế bạn muốn phân bổ.
develCuy

30
  1. chạy linux;
  2. khởi động với mem=nn[KMG]tham số khởi động kernel

(xem trong linux / Documentation / kernel -ameter.txt để biết chi tiết).


24

Nếu bạn có các công cụ GNU cơ bản ( sh, grep, yeshead) bạn có thể làm điều này:

yes | tr \\n x | head -c $BYTES | grep n
# Protip: use `head -c $((1024*1024*2))` to calculate 2MB easily

Điều này hoạt động vì grep tải toàn bộ dòng dữ liệu trong RAM (tôi đã học được điều này theo một cách khá đáng tiếc khi lấy một hình ảnh đĩa). Điểm mấu, được tạo ra bởi yes, dòng mới thay thế, sẽ là dài vô hạn, nhưng bị hạn chế bởi headđể $BYTESbyte, do đó grep sẽ nạp $ byte trong bộ nhớ. Bản thân Grep sử dụng như 100-200KB đối với tôi, bạn có thể cần phải trừ đi để có số tiền chính xác hơn.

Nếu bạn cũng muốn thêm một hạn chế về thời gian, điều này có thể được thực hiện khá dễ dàng trong bash(sẽ không hoạt động sh):

cat <(yes | tr \\n x | head -c $BYTES) <(sleep $NumberOfSeconds) | grep n

Điều <(command)này dường như ít được biết đến nhưng thường cực kỳ hữu ích, thông tin thêm về nó ở đây: http://tldp.org/LDP/abs/html/ process-sub.html

Sau đó, để sử dụng cat: catsẽ đợi các đầu vào hoàn thành cho đến khi thoát ra và bằng cách giữ một trong các đường ống mở, nó sẽ giữ cho grep sống.

Nếu bạn có pvvà muốn từ từ tăng RAM, hãy sử dụng:

yes | tr \\n x | head -c $BYTES | pv -L $BYTESPERSEC | grep n

Ví dụ:

yes | tr \\n x | head -c $((1024*1024*1024)) | pv -L $((1024*1024)) | grep n

Sẽ sử dụng tối đa một gigabyte với tốc độ 1MB mỗi giây. Là một phần thưởng bổ sung, pvsẽ cho bạn thấy tỷ lệ sử dụng hiện tại và tổng số sử dụng cho đến nay. Tất nhiên điều này cũng có thể được thực hiện với các biến thể trước đó:

yes | tr \\n x | head -c $BYTES | pv | grep n

Chỉ cần chèn | pv |phần này sẽ cho bạn thấy trạng thái hiện tại (thông lượng và tổng số, theo mặc định, tôi nghĩ - nếu không hãy xem trang người đàn ông (ual)).


Tại sao câu trả lời khác? Câu trả lời được chấp nhận khuyên bạn nên cài đặt một gói (Tôi cá là có một bản phát hành cho mọi chipset mà không cần người quản lý gói); câu trả lời được bình chọn hàng đầu khuyên bạn nên biên dịch chương trình C (Tôi chưa cài đặt trình biên dịch hoặc chuỗi công cụ để biên dịch cho nền tảng mục tiêu của bạn); câu trả lời được bình chọn hàng đầu thứ hai khuyên bạn nên chạy ứng dụng trong máy ảo (vâng, hãy để tôi chỉ cần sdcard nội bộ của điện thoại này qua usb hoặc một cái gì đó và tạo một hình ảnh hộp ảo); phần ba đề nghị sửa đổi một cái gì đó trong chuỗi khởi động không lấp đầy RAM như mong muốn; cái thứ tư chỉ hoạt động trong khoảng thời gian gắn kết / dev / shm (1) và (2) là lớn (đáp ứng nhu cầu gốc); thứ năm kết hợp nhiều thứ ở trên mà không có mã mẫu; thứ sáu là một câu trả lời tuyệt vời nhưng tôi đã không thấy câu trả lời này trước khi đưa ra cách tiếp cận của riêng mình, Vì vậy, tôi nghĩ rằng tôi nên thêm cái riêng của mình, cũng bởi vì nó ngắn hơn để nhớ hoặc gõ nếu bạn không thấy rằng dòng memblob thực sự là mấu chốt của vấn đề; thứ bảy một lần nữa không trả lời câu hỏi (sử dụng ulimit để giới hạn một quá trình thay thế); thứ tám cố gắng để bạn cài đặt python; người thứ chín nghĩ rằng tất cả chúng ta đều rất không sáng tạo và cuối cùng, người thứ mười đã viết chương trình C ++ của riêng mình, điều này gây ra vấn đề tương tự như câu trả lời được bình chọn hàng đầu.


giải pháp đáng yêu. Chỉ có trục trặc là mã thoát của cấu trúc là 1 vì grep không tìm thấy kết quả khớp. Không có giải pháp nào từ stackoverflow.com/questions/6550484/ dường như khắc phục nó.
Holger Brandl

@HolgerBrandl Điểm tốt, tôi sẽ không biết cách khắc phục điều đó. Đây là lần đầu tiên tôi nghe nói set -e, vì vậy tôi mới học được điều gì đó :)
Luc

$ SECONDS dường như không phải là một lựa chọn tốt vì nó là một biến tích hợp phản ánh thời gian kể từ khi vỏ được bắt đầu. xem tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html
Holger Brandl

@HolgerBrandl Bắt tốt, tôi không biết điều đó. Thật tuyệt khi tìm thấy một thiết bị đầu cuối mở trong> 3 triệu giây hiện tại: D. Tôi đã cập nhật bài viết.
Lục

Kỹ thuật tuyệt vời! time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n(sử dụng bộ nhớ 10 GiB) mất 1 phút 46 giây. Chạy chương trình eatmemory của julman99 tại github.com/julman99/eatmemory mất 6 giây. ... Chà, cộng với thời gian tải xuống và biên dịch, nhưng nó không có vấn đề gì ... và rất nhanh chóng ... trên máy RHEL6.4 của tôi. Tuy nhiên, tôi thích giải pháp này. Tại sao phải phát minh lại bánh xe?
Mike S

18

Tôi giữ một chức năng để làm một cái gì đó tương tự trong dotfiles của tôi. https://github.com/sagotsky/.dotfiles/blob/master/.fifts#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
}

1
Đây là giải pháp IMHO đẹp nhất, vì về cơ bản nó chỉ cần dd để hoạt động, tất cả những thứ khác có thể được xử lý trong bất kỳ shell nào. Lưu ý rằng nó thực sự đòi hỏi gấp đôi bộ nhớ so với dữ liệu dd tạo ra, ít nhất là tạm thời. Đã thử nghiệm trên debian 9, dấu gạch ngang 0,5,8-2,4. Nếu bạn sử dụng bash để chạy phần MEMBLOB, nó sẽ trở nên rất chậm và sử dụng gấp bốn lần số lượng dd tạo ra.
P.Péter

16

Làm thế nào để vượt qua một giải pháp python đơn giản?

#!/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)

7
Điều đó có thể sẽ nhanh chóng được hoán đổi, có rất ít tác động thực tế đến áp lực bộ nhớ (trừ khi bạn cũng điền vào tất cả các trao đổi, thường sẽ mất một lúc, thường)
Joachim Sauer

1
Tại sao một trao đổi unix trong khi có RAM có sẵn? Đây thực sự là một cách hợp lý để đuổi bộ đệm đĩa khi cần.
Alexander Shcheblikin

@AlexanderShcheblikin Câu hỏi này không phải về việc xóa bộ đệm đĩa (rất hữu ích cho kiểm tra hiệu năng nhưng không phải để kiểm tra tài nguyên thấp).
Gilles

1
Giải pháp này hoạt động để tăng tốc một hoặc hai Gig trong các thử nghiệm của tôi, mặc dù tôi đã không cố gắng làm căng thẳng trí nhớ của mình. Nhưng, @JoachimSauer, người ta có thể đặt sysctl vm.swappiness=0và hơn nữa đặt vm.min_free_kbytes thành một số nhỏ, có thể là 1024. Tôi chưa thử, nhưng các tài liệu nói rằng đây là cách bạn kiểm soát sự nhanh chóng của việc hoán đổi ... bạn nên thực sự có thể làm cho nó khá chậm, đến mức gây ra tình trạng OOM trên máy của bạn. Xem kernel.org/doc/Documentation/sysctl/vm.txtkernel.org/doc/gorman/html/understand/understand005.html
Mike S

chỉ cần một lớp lót cho 1GB: python -c "x = (1 * 1024 * 1024 *
1024/8

10

Làm thế nào về ramfs nếu nó tồn tại? Gắn nó và sao chép trên một tập tin lớn? Nếu không có /dev/shmvà không có ramfs - tôi đoán một chương trình C nhỏ có một malloc lớn dựa trên một số giá trị đầu vào? Có thể phải chạy nó vài lần cùng một lúc trên hệ thống 32 bit với rất nhiều bộ nhớ.


8

Nếu bạn muốn kiểm tra một quy trình cụ thể với bộ nhớ hạn chế, bạn nên sử dụng ulimitđể hạn chế lượng bộ nhớ phân bổ.


2
Trên thực tế, điều này không hoạt động trên linux (dunno về các * nixes khác). 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.
Patrick

4

Tôi nghĩ rằng đây là một trường hợp đặt câu hỏi sai và sự tỉnh táo bị nhấn chìm bởi những người cạnh tranh cho câu trả lời sáng tạo nhất. Nếu bạn chỉ cần mô phỏng các điều kiện OOM, bạn không cần phải lấp đầy bộ nhớ. Chỉ cần sử dụng một phân bổ tùy chỉnh và nó thất bại sau một số phân bổ nhất định. Cách tiếp cận này dường như hoạt động đủ tốt cho SQLite .


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.