空きメモリの90%を埋める方法は?


181

リソースの少ないテストをいくつか行いたいので、そのために空きメモリの90%をいっぱいにする必要があります。

*nixシステムでこれを行うにはどうすればよいですか?


3
本当に* nixシステムで動作する必要がありますか?
CVn

31
メモリをいっぱいにする代わりに、メモリを制限したVMを作成できますか(Docker、Vagrant、または同様のものを使用)。
アベンディゴ

4
@abendigoここで紹介するソリューションの多くはQAに役立ちます。特定のプラットフォームを持たない汎用OSにはVMまたはカーネルブートパラメーターが役立ちますが、ターゲットシステムのメモリ仕様がわかっている組み込みシステムには役立ちます。空きメモリがいっぱいになります。
エデュアルドフロリネスク

2
ここで得点することに他の誰かが少しショックを受けた場合:meta.unix.stackexchange.com/questions/1513/…
goldilocks

回答:


157

stress-ngは、POSIXシステムでのcpu / mem / io / hddストレスをシミュレートするワークロードジェネレーターです。この呼び出しは、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

/ / etcを使用/proc/meminfoして呼び出しを調整します。ポータブルが必要な場合。free(1)vm_stat(1)


3
ストレス--vm-bytes $(awk '/ MemFree / {printf "%d \ n"、$ 2 * 0.097;}' </ proc / meminfo)k --vm-keep -m 10
Robert

1
MemFreeのほとんどはOSによって保持されているため、代わりにMemAvailableを使用しました。これにより、Cent OS 7で92%の使用率が得られました。stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' < /proc/meminfo)k --vm-keep -m 1
kujiy18年

知っておくと、MemAvailableは「スワップせずに新しいアプリケーションを起動するために使用可能なメモリ量の見積もり」に追加されました。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
追加のメモとして、両方--vm 1 and --vm-keepを提供することは非常に重要です。単純に--vm-bytes何もしないので、必要なだけのメモリを割り当てることができると思い込まれます。256Gのメモリを割り当てて自分自身の健全性をチェックしようとするまで、私はこれに少し困りました。これは答えの欠陥ではなく、正しいフラグを提供しますが、追加の注意が必要です。
ffledgling

これがある理由です-m 1。ストレスのマンページによると、次の-m N略です--vm N:スポーンNワーカーの回転malloc()/free()
tkrennwa

92

Cプログラムをmalloc()必要なメモリに書き込んでmlock()から、メモリがスワップアウトされるのを防ぐために使用できます。

次に、プログラムにキーボード入力を待機させ、メモリのロックを解除し、メモリを解放して終了します。


25
昔、同様のユースケースをテストする必要がありました。そのメモリに何かを書き込むまで、実際には割り当てられない(つまり、ページフォールトが発生するまで)ことを観察しました。mlock()がそれを処理するかどうかはわかりません。
プーナ

2
@siriに同意します。ただし、使用しているUNIXの種類によって異なります。
アンソニー

2
いくつかのインスピレーションコードについて。さらに、メモリをロック解除/解放する必要はないと思います。プロセスが終了すると、OSがそれを行います。
セバスチャン

9
おそらく実際にメモリに書き込む必要があります。mallocだけを行うと、カーネルはオーバーコミットするだけです。たとえば、Linuxは、実際にメモリを解放せずにmallocを正常に返し、書き込み時にのみ実際にメモリを割り当てます。win.tue.nl/~aeb/linux/lk/lk-9.html
Bjarke Freund-Hansen

7
@Sebastian:calloc同じ問題IIRCに遭遇します。すべてのメモリは、同じ読み取り専用のゼロ化されたページを指すだけです。書き込みを試みるまで、実際には割り当てられません(読み取り専用であるため機能しません)。私が知っていることを本当に確信する唯一の方法はmemset、バッファ全体を実行することです。詳細については、次の回答を参照してくださいstackoverflow.com/a/2688522/713554
レオ

45

メモリが限られているVMを実行してソフトウェアをテストすることは、ホストマシンのメモリをいっぱいにするよりも効率的なテストになることをお勧めします。

また、この方法には、メモリ不足の状況により他の場所でOOMエラーが発生してOS全体がハングする場合、他の有用なプロセスが実行されているマシンではなく、テストするVMのみがハングするという利点があります。

また、テストがCPUまたはIOを集中的に使用しない場合、さまざまな低メモリサイズのVMファミリでテストのインスタンスを同時に実行できます。


31

この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

8
すべての* nixに/ dev / shmがあるわけではありません。ポータブルなアイデアはありますか?
タデウシュA.カドウボウスキ

場合はpvインストールされている、それは数を見ることができます:dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024
Otheus

1
速度が必要な場合は、この方法が正しい選択です!数秒で必要な量のRAMを割り当てるためです。/ dev / urandomでリレーしないでください。CPUを100%使用し、RAMが大きい場合は数分かかります。それでも、/ dev / shmは、最新のUbuntu / Debianディストリビューションでは相対的なサイズを持ち、デフォルトは物理RAMの50%です。/ dev / shmを再マウントするか、新しいマウントポイントを作成できることを願っています。割り当てたい実際のサイズであることを確認してください。
develCuy

30
  1. Linuxを実行します。
  2. でブートmem=nn[KMG]カーネルブートパラメータ

(詳細については、linux / Documentation / kernel-parameters.txtを参照してください)。


24

あなたは、基本的なGNUツール持っている(場合はsh、をgrepyeshead)あなたはこれを行うことができます。

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

これは、grepがRAMのデータ行全体をロードするために機能します(ディスクイメージをgrepするときに、これはかなり残念な方法で学習しました)。で生成された行は、yes改行を置き換えて無限に長くheadなり$BYTESますが、バイトに制限されているため、grepはメモリに$ BYTESをロードします。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を参照してください。

次に、catcatを使用するために、終了するまで入力が完了するのを待ち、パイプの1つを開いたままにしておくと、grepが存続します。

pvRAMの使用を徐々に増やしたい場合:

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の速度で最大1ギガバイトを使用します。追加ボーナスとして、pv現在の使用率とこれまでの合計使用量が表示されます。もちろん、これは以前のバリアントでも実行できます。

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

| pv |パーツを挿入するだけで、現在のステータスが表示されます(デフォルトでは、スループットと合計、そうでない場合はman(ual)ページを参照してください)。


なぜ別の答えですか?受け入れられた答えは、パッケージのインストールを推奨しています(パッケージマネージャーを必要とせずにすべてのチップセットのリリースがあるはずです)。上位の回答では、Cプログラムのコンパイルを推奨しています(ターゲットプラットフォーム用にコンパイルするためのコンパイラまたはツールチェーンがインストールされていませんでした)。2番目に上位に選ばれた回答では、VMでアプリケーションを実行することを推奨しています(そう、この電話の内部SDカードをusbなどでddし、virtualboxイメージを作成します)。3番目は、ブートシーケンスで、必要に応じてRAMを一杯にしないものを変更することを提案しています。4番目は/ dev / shmマウントポイント(1)が存在し、(2)が大きい場合にのみ機能します(再マウントにはルートが必要です)。5番目は、サンプルコードなしで上記の多くを組み合わせています。6番目は素晴らしい答えですが、私は自分のアプローチを考え出す前にこの答えを見ませんでした、だから、私は自分で追加しようと思った。それは、memblob行が実際に問題の核心であることがわからない場合、覚えたり入力したりするのが短いからだ。7番目もまた質問に答えません(代わりにulimitを使用してプロセスを制限します)。8番目は、pythonのインストールを試みます。9人目は私たちは皆非常に創造的ではないと考え、最後に10人目は彼自身のC ++プログラムを作成しました。


素敵なソリューション。唯一の不具合は、grepが一致を見つけられないため、構造の終了コードが1であることです。stackoverflow.com/questions/6550484/…のソリューションはどれも解決しないようです。
ホルガーブランドル

@HolgerBrandl良い点、私はそれを修正する方法を知りません。これは私が聞いたのは初めてなset -eので、私は何かを学んだだけです:)
リュック

$ SECONDSは、シェルが開始されてからの時間を反映する組み込み変数であるため、適切な選択ではないようです。tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.htmlを
Holger Brandl

@HolgerBrandl良いキャッチ、私はそれを知りませんでした。現在、300万秒以上開いている端末を見つけるのはクールです:D。投稿を更新しました。
リュック

クールなテクニック!time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n(10 GiBメモリを使用)1分46秒かかります。github.com/julman99/eatmemoryでjulman99のeatmemoryプログラムを実行するには、6秒かかります。...まあ、それに加えてダウンロードとコンパイルに時間がかかりましたが、問題なくコンパイルされました...そして非常に迅速に... RHEL6.4マシンで。それでも、私はこのソリューションが好きです。なぜ車輪を再発明するのですか?
マイクS

18

私は、ドットファイルで似たようなことをする関数を保持しています。 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
}

1
私見では、これは基本的にddのみが必要であり、他のすべてのものはどのシェルでも回避できるため、これが最も良いソリューションです。少なくとも一時的に、ddが生成するデータの2倍のメモリを実際に要求することに注意してください。Debian 9、ダッシュ0.5.8-2.4でテスト済み。MEMBLOBパーツの実行にbashを使用すると、非常に遅くなり、ddが生成する量の4倍を使用します。
P.Peter

16

単純なpythonソリューションはどれほどありますか?

#!/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
それはおそらくすぐに(通常は、しばらく時間がかかるであろう、あなたにも、すべてのスワップを埋める場合を除く)、メモリ圧力にほとんどの実際の影響を与えて、スワップアウトされます
ヨアヒム・ザウアー

1
使用可能なRAMがあるのにUNIXがスワップするのはなぜですか?これは実際、必要なときにディスクキャッシュを削除するもっともらしい方法です。
アレクサンダーシュチェブリキン

@AlexanderShcheblikinこの質問は、ディスクキャッシュの排除に関するものではありません(パフォーマンステストには役立ちますが、低リソーステストには役立ちません)。
ジル

1
このソリューションは、私のテストで1つか2つのGigを減らすのに役立ちましたが、記憶を強調しようとはしませんでした。しかし、@ JoachimSauer、sysctl vm.swappiness=0vm.min_free_kbytesを1024程度の小さな値に設定し、さらに設定することができます。私は試していませんが、これはスワップアウトの迅速さを制御する方法であるとドキュメントは述べています...あなたのマシンでOOM状態を引き起こすポイントまで、実際にそれをかなり遅くすることができます。kernel.org/doc/Documentation/sysctl/vm.txtおよびkernel.org/doc/gorman/html/understand/understand005.htmlを
Mike S

1GBの1つのライナー:python -c "x =(1 * 1024 * 1024 * 1024/8)*(0、); raw_input()"
adrianlzt

10

ramfsが存在する場合はどうですか?マウントして大きなファイルにコピーしますか?/dev/shmramfsがまったくない場合-入力値に基づいて大きなmallocを実行する小さなCプログラムですか?大量のメモリを搭載した32ビットシステムで一度に数回実行する必要がある場合があります。


8

限られたメモリで特定のプロセスをテストしたい場合ulimitは、割り当て可能なメモリの量を制限するために使用した方が良いかもしれません。


2
実際、これはLinuxでは機能しません(他の* nixについては知らない)。man setrlimitRLIMIT_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.
パトリック

4

これは、最も創造的な答えを求めて競争する人々によって間違った質問と正気が失われていることを尋ねる場合だと思います。OOM条件のみをシミュレートする必要がある場合は、メモリをいっぱいにする必要はありません。カスタムアロケーターを使用し、一定数の割り当て後に失敗するようにします。このアプローチは、SQLiteで十分に機能するようです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.