Boş hafızanın% 90'ı nasıl doldurulur?


181

Bazı düşük kaynakları test etmek istiyorum ve bunun için boş hafızanın% 90'ının dolu olmasına ihtiyacım var.

Bunu bir *nixsistemde nasıl yapabilirim ?


3
Gerçekten herhangi bir * nix sisteminde çalışmak zorunda mı?
CVn

31
Jut yerine bellek doldurmak yerine, sınırlı miktarda belleğe sahip bir VM (docker veya serseri veya benzeri bir şey kullanarak) oluşturabilir misiniz?
abendigo

4
@abendigo QA için burada sunulan çözümlerin çoğu yararlıdır: genel amaçlı bir işletim sistemi için belirli bir platform olmadan VM veya çekirdek önyükleme parametreleri faydalı olabilir, ancak hedeflenen sistemin bellek özelliklerini bildiğiniz gömülü bir sistem için boş hafızanın doldurulması için gidin.
Eduard Florinescu

2
Buradaki puanlamadan başka birinin biraz şok olması durumunda: meta.unix.stackexchange.com/questions/1513/… ?
goldilocks

Yanıtlar:


157

stres ng POSIX sistemlerinde işlemci / MEM / io / HDD stres simüle eden bir iş yükü jeneratör. Bu çağrı Linux <3.14'te hile yapmalı:

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

Linux> = 3.14 için, MemAvailabledeğiştirmeden yeni işlemler için kullanılabilir belleği tahmin etmek yerine kullanabilirsiniz :

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

/proc/meminfoAramayı free(1)/ vm_stat(1)/ etc ile uyarlayın . taşınabilir ihtiyacınız varsa.


3
stres --vm-bytes $ (awk '/ MemFree / {printf "% d \ n", $ 2 * 0,097;}' </ proc / meminfo) k --vm-keep -m 10
Robert

1
MemFree'nin çoğu işletim sistemi tarafından tutulur, bu yüzden onun yerine MemAvailable'i kullandım. Bu bana Cent OS 7'de% 92 kullanım stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' < /proc/meminfo)k --vm-keep -m 1
sağladı

bilmek iyi, MemAvailable "yeni uygulamalara başlamak için ne kadar bellek kullanılabileceğini değiştirmeden değiştirmeye" eklenmiş , bkz. git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ … Ve git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/…
tkrennwa

1
Ek bir not gibi, ikisini --vm 1 and --vm-keepde sağlamak çok önemlidir. Basitçe --vm-byteshiçbir şey yapmaz ve ihtiyaç duyduğunuz / istediğiniz kadar bellek ayırabileceğinizi düşünerek yanlış yönlendirilmiş olabilirsiniz. 256G bellek tahsis ederek kendimi kontrol etmeye çalışıncaya kadar biraz ısırdım. Bu cevapta bir kusur değil, sadece ek bir dikkat, doğru bayrakları sağlar.
Mar’a

Bu yüzden var -m 1. Strese göre manpage, -m N--vm NNmalloc()/free()
şunun

92

malloc()İstenilen hafızaya bir C programı yazabilir ve ardından mlock()hafızanın değiştirilmesini önlemek için kullanabilirsiniz .

Ardından programın klavye girişi için beklemesine izin verin, belleğin kilidini açın, belleği boşaltın ve çıkın.


25
Uzun zaman önce benzer kullanım durumlarını test etmek zorunda kaldım. Bu hafızaya bir şey yazana kadar, aslında tahsis edilmeyeceğini gözlemledim (yani sayfa hatası gerçekleşene kadar). Mlock () 'un bununla ilgilenip ilgilenmediğinden emin değilim.
Poorna

2
@Siri ile aynı fikirdeyim; ancak, hangi UNIX değişkenini kullandığınıza bağlıdır.
Anthony,

2
Bazı ilham kodu. Dahası, bence sen / kilidini belleği boşaltmak gerekmez . İşleminiz sona erdiğinde, işletim sistemi bunu sizin için yapacak.
Sebastian

9
Muhtemelen hafızaya yazmalısın, çekirdeği sadece malloc olursan çekirdeği yenebilir. Eğer konfigüre edilirse, örneğin Linux, malloc’un hafızayı boşaltmadan başarılı bir şekilde geri dönmesini sağlar ve sadece hafızaya yazıldığında hafızayı ayırır. Bkz. Win.tue.nl/~aeb/linux/lk/lk-9.html
Bjarke Freund-Hansen

7
@Sebastian: callocAynı problemle karşılaşacaksınız IIRC. Tüm bellek sadece aynı salt okunur sıfırlanmış sayfaya işaret edecektir. Siz yazmaya yazmaya başlayıncaya kadar aslında tahsis edilmeyecek (salt okunur olduğu için çalışmayacak). Gerçekten bildiğimden emin olmanın tek yolu, memsettampondan bir tane yapmak. Daha fazla bilgi için aşağıdaki cevaba bakınız. Stackoverflow.com/a/2688522/713554
Leo

45

Sınırlı belleğe sahip bir VM çalıştırmayı ve bunun içindeki yazılımı test etmeyi öneririm, ana makinedeki belleği doldurmaya çalışmaktan daha etkili bir test olur.

Bu yöntemin avantajı, düşük bellek durumunun başka yerlerde OOM hatalarına neden olması ve tüm işletim sistemini askıya alması durumunda, üzerinde çalışmakta olduğunuz diğer yararlı işlemlerin olabileceği makinenize değil, yalnızca test ettiğiniz VM'yi asmanızdır.

Ayrıca, testiniz CPU veya IO yoğun değilse, testlerin örneklerini çeşitli düşük bellek boyutlarına sahip bir VM ailesi üzerinde eşzamanlı olarak çalıştırabilirsiniz.


31

Bu HN yorumundan: https://news.ycombinator.com/item?id=6695581

/ Dev / shm komutunu dd veya benzeri bir dosyayla doldurmanız yeterlidir.

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

8
Bütün * nix'lerde / dev / shm yoktur. Daha taşınabilir bir fikir var mı?
Tadeusz A. Kadłubowski

Eğer pvyüklü, bu sayısını görmek için yardımcı olur:dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024
Otheus

1
Hız istiyorsanız, bu yöntem doğru seçimdir! Çünkü istenen miktarda RAM'i birkaç saniye içinde tahsis eder. / Dev / urandom'a aktarmayın,% 100 CPU kullanır ve RAM'iniz büyükse birkaç dakika alır. YET, / dev / shm, modern Ubuntu / Debian dağıtımlarında göreceli bir boyuta sahiptir, fiziksel RAM'in% 50'sine varan bir boyuta sahiptir. Umarım / dev / shm dosyasını yeniden birleştirebilir veya yeni bir bağlantı noktası oluşturabilirsiniz. Sadece ayırmak istediğiniz gerçek boyutta olduğundan emin olun.
develCuy

30
  1. linux çalıştırmak;
  2. ile önyükleme mem=nn[KMG]çekirdek önyükleme parametresi

(Ayrıntılar için linux / Documentation / kernel-parameters.txt dosyasına bakın).


24

Eğer temel GNU araçları (varsa sh, grep, yesve head) bunu yapabilirsiniz:

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

Bu, grep'in RAM'deki tüm veri hattını yüklediği için işe yarıyor (bunu bir disk görüntüsünü çizerken talihsiz bir şekilde öğrendim). Tarafından üretilen çizgi, yesyerini satırbaşıyla, sonsuz uzun olacak, ama sınırlıdır headiçin $BYTESbayt, böylece grep bellekte $ BYTES yükleyecektir. Grep benim için 100-200KB gibi kullanıyor, daha kesin bir miktar için onu çıkarmanız gerekebilir.

Ayrıca bir zaman kısıtlaması eklemek isterseniz, bu işlem oldukça kolay bir şekilde yapılabilir bash(çalışmaz sh):

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

Bu <(command)şey az bilinen gibi görünüyor ancak burada son derece yararlı, burada daha fazla bilgi bulabilirsiniz: http://tldp.org/LDP/abs/html/process-sub.html

Daha sonra, kullanım için cat: catgirdilerin çıkana kadar tamamlanmasını bekleyecek ve borulardan birini açık tutup, hayatta kalmaya devam edecektir.

Eğer varsa pvve yavaş yavaş RAM kullanımını artırmak istiyor:

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

Örneğin:

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

Saniyede 1 MB hızında gigabayt'a kadar kullanacaktır. Ek bir bonus olarak, pvgeçerli kullanım oranını ve şu ana kadar toplam kullanım miktarını gösterecektir. Tabii ki bu daha önceki değişkenlerle de yapılabilir:

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

Sadece | pv |parçanın yerleştirilmesi mevcut durumu gösterecektir (verim ve toplam, varsayılan olarak, sanırım - aksi halde man (ual) sayfasını görün).


Neden başka bir cevap? Kabul edilen cevap bir paket kurulmasını önerir (İddiaya girerim bir paket yöneticisine ihtiyaç duymadan her yonga seti için bir sürüm vardır); En iyi oylanan cevap, bir C programının derlenmesini önerir (hedef platformunuz için derlemek için kurulmuş bir derleyicim veya araç zincirim yoktu); ikinci en iyi oylama yanıtı, uygulamanın bir VM'de çalıştırılmasını önerir (evet, bu telefonun dahili sd kartını usb veya başka bir şey üzerinden yapmama izin ver ve sanal kutu görüntüsü oluşturmama izin ver); Üçüncüsü, önyükleme sırasındaki RAM'i istenen şekilde doldurmayan bir şeyi değiştirmenizi önerir; dördüncüsü sadece / dev / shm mountpoint (1) var olduğu ve (2) büyük olduğu sürece çalışır (remounting root root); beşinci, yukarıdakilerin çoğunu örnek kod olmadan birleştirir; Altıncı büyük bir cevap ama benim kendi yaklaşımımı bulmadan önce bu cevabı görmedim. bu yüzden kendi kendime ekleyeceğimi düşündüm, çünkü memblob çizgisinin aslında maddenin kaygısı olduğunu görmüyorsanız hatırlamak veya yazmak daha kısadır; yedinci soruya cevap vermiyor (bunun yerine süreci sınırlamak için ulimit kullanıyor); sekizinci, python yüklemenizi sağlamaya çalışır; Dokuzuncu, hepimizin çok yaratıcı olmadığını düşünüyor ve nihayetinde onuncu, C + programını yazdı;


güzel çözüm. Tek aksaklık, yapının çıkış kodunun 1 olmasıdır, çünkü grep bir eşleşme bulamaz. Stackoverflow.com/questions/6550484/… adresindeki çözümlerin hiçbiri sorunu çözmedi.
Holger Brandl

@ HolgerBrandl İyi nokta, bunu nasıl düzelteceğimi bilemem. İlk defa duyuyorum set -e, bu yüzden bir şey öğrendim :)
Luc

$ SECONDS, kabuk başlatıldığından beri geçen zamanı yansıtan yerleşik bir değişken olduğundan iyi bir seçim gibi görünmüyor. bkz. tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html
Holger Brandl

@ HolgerBrandl İyi yakalamak, bunu bilmiyordum. Şu anda> 3 milyon saniyelik açık bir terminal bulmak biraz havalı: D. Gönderiyi güncelledim.
Luc

Harika teknik! time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n(10 GiB belleği kullanın) 1 dakika 46 saniye sürer. Julman99'ın eatmemory programını github.com/julman99/eatmemory adresinde çalıştırmak 6 saniye sürer. ... Eh, artı indirme ve derleme zamanı, ancak RHEL6.4 makinemde hiç sorun yaşamadan ... ve çok hızlı bir şekilde derlendi. Yine de bu çözümü sevdim. Neden tekerleği yeniden icat ettin?
Mike S

18

Nokta dosyalarımda benzer bir şey yapmak için bir işleve sahibim. 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
Bu en güzel çözüm IMHO, aslında sadece çalışmak için dd'ye ihtiyaç duyduğundan, diğer tüm şeyler herhangi bir kabukta çalışılabilir. En azından geçici olarak, dd verilerinin ürettiğinden iki kat daha fazla bellek talep ettiğini unutmayın. Debian 9'da test edildi, tire 0.5.8-2.4. MEMBLOB bölümünü çalıştırmak için bash kullanırsanız, gerçekten yavaşlar ve dd'nin ürettiği miktarın dört katı kullanılır.
P.Péter

16

Basit bir python çözümü ne kadar abount?

#!/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
Bu muhtemelen hızlı bir şekilde değiştirilecektir, bellek baskısı üzerinde çok az gerçek etkiye sahiptir (tüm değiş tokuşu doldurmazsanız, bu genellikle bir süre alacaktır)
Joachim Sauer

1
Kullanılabilir RAM varken neden unix takas edildi? Bu aslında gerektiğinde disk önbelleğini boşaltmanın kolay bir yoludur.
Alexander Shcheblikin,

@AlexanderShcheblikin Bu soru, disk önbelleğini boşaltmakla ilgili değildir (performans testi için yararlıdır, ancak düşük kaynak testleri için değil).
Gilles

1
Bu çözüm, testlerimde bir ya da iki kez bir araya gelmeye çalıştı, ancak hafızamı vurgulamaya çalışmamıştım. Ama, @JoachimSauer, biri vm.min_free_kbytes ayarını yapabilir sysctl vm.swappiness=0ve daha da küçük bir sayıya, belki de 1024'e ayarlayabilirdi. Daha önce denemedim, ancak doktorlar bunun değiş tokluğunun nasıl kontrol edildiğini söylüyor ... Makinenizde bir OOM durumuna neden olan noktaya kadar onu gerçekten yavaşlatabilir. Bkz. Kernel.org/doc/Documentation/sysctl/vm.txt ve kernel.org/doc/gorman/html/understand/understand005.html
Mike S

1GB için tek bir astar: python -c "x = (1 * 1024 * 1024 *
1024/8

10

Eğer varsa ramfs'a ne dersiniz? Takın ve büyük bir dosya üzerine kopyalayın? Eğer /dev/shmhiçbir ramfs yoksa ve yok - Sanırım bazı girdi değerlerine dayanan büyük bir malloc yapan küçük bir C programı var mı? Çok fazla hafızası olan 32 bit bir sistemde birkaç defada çalıştırmanız gerekebilir.


8

Belirli bir işlemi sınırlı hafıza ile test etmek istiyorsanız ulimit, ayrılabilir hafızanın miktarını sınırlandırmak için kullanmaktan daha iyi olabilirsiniz .


2
Aslında bu linux üzerinde çalışmaz (diğer * ekler hakkında bilgisiz). 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

Bence bu, en yaratıcı cevap için yarışan insanlar tarafından yanlış soruyu sorma ve akıl sağlığını boğma durumu. Yalnızca OOM koşullarını simüle etmeniz gerekiyorsa, belleği doldurmanız gerekmez. Sadece özel bir tahsisatçı kullanın ve belirli sayıda tahsisattan sonra başarısız olmasını sağlayın. Bu yaklaşım SQLite için yeterince iyi çalışıyor gibi görünüyor .


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.