Tự động hủy một tiến trình nếu vượt quá một lượng RAM nhất định


12

Tôi làm việc trên các tập dữ liệu quy mô lớn. Khi kiểm tra phần mềm mới, đôi khi một tập lệnh sẽ lẻn vào tôi, nhanh chóng lấy tất cả RAM có sẵn và khiến máy tính để bàn của tôi không sử dụng được. Tôi muốn một cách để đặt giới hạn RAM cho một quy trình để nếu vượt quá số tiền đó, nó sẽ tự động bị giết. Một giải pháp dành riêng cho ngôn ngữ có thể sẽ không hoạt động, vì tôi sử dụng tất cả các loại công cụ khác nhau (R, Perl, Python, Bash, v.v.).

Vì vậy, có một số loại màn hình theo dõi quá trình sẽ cho phép tôi đặt một lượng RAM ngưỡng và tự động giết một tiến trình nếu nó sử dụng nhiều hơn?



@ Uri: Tại chủ đề đó tôi chỉ có một phần (chỉ dành cho phần cpu trong câu hỏi của tôi) - và không tối ưu - trả lời. Anh ta hỏi về việc sử dụng RAM.
Chriskin

1
Uri, hoàn toàn thiếu ý tưởng hữu ích trong chủ đề đó. Đăng một liên kết đến nó không đặc biệt hữu ích.
chrisamiller

1
Hrmm - chủ đề siêu người dùng này dường như có một đề xuất hợp lý bằng cách sử dụng ulimit: superuser.com/questions/66383/restrict-ram-for-user-or-
Process

Câu trả lời:


11

Tôi ghét phải là người trả lời câu hỏi của chính mình, nhưng sáng nay tôi đã tìm thấy một phương pháp thay thế, được gói gọn trong một tiện ích nhỏ xinh. Nó sẽ giới hạn thời gian CPU hoặc tiêu thụ bộ nhớ:

https://github.com/pshved/timeout

Tôi sẽ cho người này một phát súng đầu tiên nhưng ủng hộ Amey Jah vì câu trả lời hay. Tôi sẽ kiểm tra xem nếu cái này làm tôi thất bại.


5
+1 Trả lời câu hỏi của riêng bạn là OK !
Tom Brossman

10

Tôi sẽ khuyên không nên làm điều đó . Theo đề xuất của @chrisamiller, cài đặt ulimit sẽ giới hạn RAM có sẵn trong quá trình.

Nhưng nếu bạn vẫn khăng khăng thì hãy làm theo thủ tục này.

  1. Lưu tập lệnh sau dưới dạng 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. Bây giờ làm cho nó thực thi.

    chmod +x killif.sh
    
  3. Bây giờ chạy tập lệnh này trên thiết bị đầu cuối. Thay thế PROCIDbằng id quá trình thực tế và SIZEvới kích thước tính bằng MB.

    ./killif.sh PROCID SIZE
    

    Ví dụ:

    ./killif.sh 132451 100
    

    Nếu SIZElà 100 thì quá trình sẽ bị hủy nếu mức sử dụng RAM của nó vượt quá 100 MB.

Chú ý: Bạn biết bạn đang cố gắng làm gì. Quá trình giết chết không phải là một ý tưởng tốt. Nếu quá trình đó có bất kỳ lệnh tắt hoặc dừng thì chỉnh sửa tập lệnh và thay thế kill -9lệnh bằng shutdownlệnh đó .


tôi sẽ cân nhắc việc ngủ ít ở đó, ví dụ ngủ 0,5 ...
Denwerko

@George Edison Làm thế nào bạn làm điều đó. Khi tôi cố gắng dán, nó đã cho tôi văn bản có định dạng kỳ lạ. Denwerko: Nơi nào bạn muốn đặt giấc ngủ. Tôi đã đặt một giấc ngủ 10 giây trong vòng lặp while
Amey Jah

2
Cảm ơn giải pháp, như đã lưu ý dưới đây, tôi có thể kiểm tra nó. Tại sao tất cả các cảnh báo nghiêm trọng về quá trình giết chết, mặc dù? Phần mềm quản lý cụm (LSF, PBS, et al) thực hiện việc này mọi lúc khi một quá trình vượt quá số lượng tài nguyên mà nó yêu cầu, không có hậu quả nghiêm trọng. Tôi đồng ý rằng đây không phải là một giải pháp tốt cho những người dùng mới có khả năng sử dụng sai, nhưng trong trường hợp phù hợp, điều này có thể khá hữu ích.
chrisamiller

@chrisamiller Tôi đã đưa ra một cảnh báo cho độc giả tương lai. Trong trường hợp của bạn, bạn biết những hàm ý nhưng người đọc tương lai của bài đăng này có thể không nhận thức được những tác động đó.
Amey Jah

2
Bạn có thể giải thích tại sao không làm điều đó?
jterm

2

Hãy thử prlimitcông cụ, từ util-linuxgói. Nó chạy một chương trình với giới hạn tài nguyên. Nó sử dụng lệnh prlimitgọi hệ thống để thiết lập các giới hạn, sau đó được thực thi hoàn toàn bởi kernel.

Bạn có thể định cấu hình 16 giới hạn, bao gồm:

  • thời lượng CPU tối đa tính bằng giây
  • số lượng quá trình người dùng tối đa
  • kích thước cài đặt thường trú tối đa ("bộ nhớ đã sử dụng")
  • kích thước tối đa một quá trình có thể khóa vào bộ nhớ
  • kích thước của bộ nhớ ảo
  • số lượng tệp mở tối đa
  • số lượng khóa tập tin tối đa
  • số tín hiệu chờ xử lý tối đa
  • byte tối đa trong hàng đợi tin nhắn POSIX

0

Điều này là quá lớn để phù hợp với một nhận xét. Tôi đã sửa đổi tập lệnh gốc của Amey để bao gồm a pgrep, vì vậy thay vì phải nhập thủ công id quy trình, bạn chỉ có thể loại trừ theo tên. Ví dụ: ./killIf.sh chrome 4000giết bất kỳ quá trình chrome nào vượt quá 4GB trong sử dụng bộ nhớ.

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

Hãy cẩn thận để chọn một chuỗi grep hẹp và giới hạn bộ nhớ đủ lớn để không giết chết các quá trình ngoài ý muốn một cách không cần thiết.

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.