Belirli bir RAM miktarını aşarsa bir işlemi otomatik olarak öldürür


13

Büyük ölçekli veri kümeleri üzerinde çalışıyorum. Yeni yazılımı test ederken, bir komut dosyası bazen üzerime gizlice girer, tüm kullanılabilir RAM'leri hızlı bir şekilde alır ve masaüstümü kullanılamaz hale getirir. Bir işlem için bir RAM sınırı belirlemenin bir yolunu istiyorum, böylece bu miktarı aşarsa, otomatik olarak öldürülür. Her türlü farklı aracı (R, Perl, Python, Bash, vb.) Kullandığım için dile özgü bir çözüm muhtemelen işe yaramaz.

Peki, eşik miktarda RAM ayarlamama ve daha fazla kullanırsa bir işlemi otomatik olarak öldürmeme izin verecek bir tür işlem monitörü var mı?



@ Uri: Bu iş parçacığında sadece kısmi bir var (sorumun yalnızca cpu kısmı için) - ve optimal değil - cevap. RAM kullanımını soruyor.
Chriskin

1
Uri, bu iş parçacığında tamamen yararlı fikirlerin eksikliği var. Bir bağlantı göndermek özellikle yararlı değildir.
chrisamiller

1
- Hrmm bu süper iplik ulimit kullanarak makul bir öneri gibi görünüyor: superuser.com/questions/66383/restrict-ram-for-user-or-process
chrisamiller

Yanıtlar:


11

Kendi sorusunu cevaplayan adam olmaktan nefret ediyorum, ama bu sabah güzel bir yardımcı programa sarılmış alternatif bir yöntem buldum. CPU süresini veya bellek tüketimini sınırlar:

https://github.com/pshved/timeout

Bunu önce deniyorum ama güzel cevap için Amey Jah'a oy veriyorum. Bu beni başarısızlığa uğrarsa kontrol edeceğim.


5
+1 Kendi sorunuzu cevaplamak sorun değil !
Tom Brossman

10

Bunu yapmamanızı şiddetle tavsiye ederim . @Chrisamiller tarafından önerildiği gibi, ulimit ayarı işlemde kullanılabilir RAM'i sınırlayacaktır.

Ama yine de ısrar ediyorsanız, bu prosedürü izleyin.

  1. Aşağıdaki komut dosyasını farklı kaydedin killif.sh:

    #!/bin/sh
    
    if [ $# -ne 2 ];
    then
        echo "Invalid number of arguments"
        exit 0
    fi
    
    while true;
    do
        SIZE=$(pmap $1|grep total|grep -o "[0-9]*")
        SIZE=${SIZE%%K*}
        SIZEMB=$((SIZE/1024))
        echo "Process id =$1 Size = $SIZEMB MB"
        if [ $SIZEMB -gt $2 ]; then
            printf "SIZE has exceeded.\nKilling the process......"
            kill -9 "$1"
            echo "Killed the process"
            exit 0
        else
            echo "SIZE has not yet exceeding"
        fi
    
        sleep 10
    done
    
  2. Şimdi çalıştırılabilir yapın.

    chmod +x killif.sh
    
  3. Şimdi bu komut dosyasını terminalde çalıştırın. PROCIDGerçek işlem kimliğiyle ve SIZEMB cinsinden boyutla değiştirin .

    ./killif.sh PROCID SIZE
    

    Örneğin:

    ./killif.sh 132451 100
    

    Eğer SIZEonun RAM kullanımı 100 MB ötesine kadar giderse 100 ardından süreç öldürülecek olduğunu.

Dikkat: Ne yapmaya çalıştığını biliyorsun. Öldürme süreci iyi bir fikir değil. Bu işlemde kapatma veya durdurma komutu varsa, komut dosyasını düzenleyin ve kill -9komutu bu shutdownkomutla değiştirin .


Ben orada küçük bir uyku koyarak düşünün, örneğin uyku 0.5 ...
Denwerko

@George Edison Bunu nasıl yaptın? Yapıştırmaya çalıştığımda garip biçimlendirilmiş metinler veriyordu. Denwerko: Uykuyu nereye koymak istersiniz. Zaten döngüde 10 saniye uyudum
Amey Jah

2
Çözüm için teşekkürler, aşağıda belirtildiği gibi, kontrol edebilirim. Öldürme süreçleriyle ilgili neden tüm korkunç uyarılar? Küme yönetim yazılımı (LSF, PBS ve diğerleri), bir işlem, istenen sonuçların miktarını aştığında ve sonuçsuz kalmadan bunu yapar. Bunun yanlış uygulama olasılığı olan yeni kullanıcılar için iyi bir çözüm olmadığını kabul ediyorum, ancak doğru koşullarda bu oldukça yararlı olabilir.
chrisamiller

@chrisamiller Gelecekteki okuyucular için bir uyarı yaptım. Sizin durumunuzda, sonuçları biliyorsunuz, ancak bu yazının gelecekteki okuyucusu bu tür etkilerin farkında olmayabilir.
Amey Jah

2
Neden yapmamanız konusunda ayrıntılı bilgi verebilir misiniz?
jterm

2

prlimitAracı util-linuxpaketten deneyin . Kaynak sınırları olan bir program çalıştırır. prlimitSınırları belirlemek için sistem çağrısını kullanır ve bu sınırlamalar daha sonra yalnızca çekirdek tarafından uygulanır.

Aşağıdakiler dahil 16 sınır yapılandırabilirsiniz:

  • saniye cinsinden maksimum CPU süresi
  • maksimum kullanıcı işlemi sayısı
  • maksimum yerleşik ayar boyutu ("kullanılmış bellek")
  • bir işlemin belleğe kilitlenebileceği maksimum boyut
  • sanal bellek boyutu
  • maksimum açık dosya sayısı
  • maksimum dosya kilidi sayısı
  • maksimum bekleyen sinyal sayısı
  • POSIX mesaj kuyruklarında maksimum bayt

0

Bu bir yoruma sığmayacak kadar büyüktü. Amey'nin orijinal komut dosyasını bir içerecek şekilde değiştirdim pgrep, bu yüzden manuel olarak işlem kimliğini girmek yerine, sadece ada göre hariç tutabilirsiniz. Örneğin, ./killIf.sh chrome 4000bellek kullanımında 4 GB'ı aşan tüm krom işlemlerini öldürür.

#!/bin/sh

# $1 is process name
# $2 is memory limit in MB

if [ $# -ne 2 ];
then
    echo "Invalid number of arguments"
    exit 0
fi

while true;
do
    pgrep "$1" | while read -r procId;
    do
        SIZE=$(pmap $procId | grep total | grep -o "[0-9]*")
        SIZE=${SIZE%%K*}
        SIZEMB=$((SIZE/1024))
        echo "Process id = $procId Size = $SIZEMB MB"
        if [ $SIZEMB -gt $2 ]; then
            printf "SIZE has exceeded.\nKilling the process......"
            kill -9 "$procId"
            echo "Killed the process"
            exit 0
        else
            echo "SIZE has not yet exceeding"
        fi
    done

    sleep 1
done

İstenmeyen işlemleri gereksiz yere öldürmemek için dar bir grep dizesi ve yeterince büyük bir bellek sınırı seçmeye dikkat edin.

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.