Попередження, коли доступна оперативна пам’ять наближається до нуля


13

Це подальше рішення щодо обмеження пам’яті для жадібних програм, які можуть збити ОС? : ulimit та групи не є зручними для користувачів, і крім того, вони не працюватимуть із програмами, які породжують окремі процеси, такі як Chrome / Chromium для кожної нової (групи) вкладок.

Просте і ефективне рішення, яке фактично використовується Windows 7, полягає в тому, щоб попередити користувача про те, що в ОС недостатньо пам'яті. Це просте спливаюче попередження запобігло мені зависання будь-якої системи, спричиненої низькою пам’яттю, у Windows, і я постійно натрапляв на них у дистрибутивах Ubuntu, які я тестував у прямому ефірі (де на встановленій оперативною пам’яті диску буде з’їсти лише 2 ГБ).

Отже, чи є спосіб автоматично попередити користувача про те, що наявна оперативна пам’ять наближається до нуля, без того, щоб користувач не повинен слідкувати за деяким гаджетом моніторингу пам'яті? Невже Конкі може бути налаштований на це?


2
Через чотири роки , схоже, періодично перевіряється free -mшлях.
Дан Даскалеску

Відповіді:


8

Перевірте ці сценарії: Потрібно попереджати програми / сценарії, коли закінчується системна пам'ять

#!/bin/bash

#Minimum available memory limit, MB
THRESHOLD=400

#Check time interval, sec
INTERVAL=30

while :
do

    free=$(free -m|awk '/^Mem:/{print $4}')
    buffers=$(free -m|awk '/^Mem:/{print $6}')
    cached=$(free -m|awk '/^Mem:/{print $7}')
    available=$(free -m | awk '/^-\/+/{print $4}')

    message="Free $free""MB"", buffers $buffers""MB"", cached $cached""MB"", available $available""MB"""

    if [ $available -lt $THRESHOLD ]
        then
        notify-send "Memory is running out!" "$message"
    fi

    echo $message

    sleep $INTERVAL

done

PHP:

#!/usr/bin/php
<?php
$alert_percent=($argc>1)?(int)$argv[1]:90;
//$interval=($argc>2):(int)$argv[2]:25;



//while(true)
//{
 exec("free",$free);

$free=implode(' ',$free);
preg_match_all("/(?<=\s)\d+/",$free,$match);

list($total_mem,$used_mem,$free_mem,$shared_mem,$buffered_mem,$cached_mem)=$match[0];

$used_mem-=($buffered_mem+$cached_mem);

$percent_used=(int)(($used_mem*100)/$total_mem);

if($percent_used>$alert_percent)
exec("notify-send 'Low Memory: $percent_used% used'");

//sleep($interval);
//}
exit();
?>

1
Сценарій працює з невеликими адаптаціями (я щойно використовував available=$(free -m | grep Mem | awk '{print $7}')). Щоб змусити роботу надсилати повідомлення з cron, зверніться до anmolsinghjaggi.wordpress.com/2016/05/11/…
morsch

Якщо мова не англійська, вільний буде виводити локалізований текст, а аналіз не вдається. Потім додайте LANG=en_US.UTF-8на початку сценарію bash.
Фредді Шиллер

2

Ще один сценарій, який я написав для цього:

#!/bin/bash
# Copyright 2019, Mikko Rantalainen
# License: MIT X License

# Minimum available memory until warning, default to 10% of total RAM (MiB)
THRESHOLD=$(grep "MemTotal:" /proc/meminfo | awk '{ printf "%d", 0.1*$2/1024}')
INTERVAL=60s

echo "Emitting a warning if less than $THRESHOLD MiB of RAM is available..."

while true; do
    meminfo=$(cat /proc/meminfo)
    free=$(echo "$meminfo" | grep "MemFree:" | awk '{ printf "%d", $2/1024}')
    available=$(echo "$meminfo" | grep "MemAvailable:" | awk '{ printf "%d", $2/1024}')
    inactive=$(echo "$meminfo" | grep "Inactive:" | awk '{ printf "%d", $2/1024}')
    reclaimable=$(echo "$meminfo" | grep "SReclaimable:" | awk '{ printf "%d", $2/1024}')
    usable=$(echo "$free + $inactive / 2 + $reclaimable / 2" | bc)
    if test -z "$available"; then
        message="Current kernel does not support MemAvailable in /proc/meminfo, aborting"
        notify-send "Error while monitoring low memory" "$message"
        echo "$message" 1>&2
        exit 1
    fi

    message="Available: $available MiB
Free: $free MiB
Maybe usable: $usable MiB"

    if [ "$available" -lt "$THRESHOLD" ]
        then
        notify-send -u critical "Low memory warning" "$message"
        echo "Low memory warning:"
    echo "$message"
    fi

    #echo "DEBUG: $message"
    sleep $INTERVAL
done

Чому o, чому notify-sendігнорує параметр тайм-аут : - / І чому немає документації про те, що таке категорії та значки запасів? Крім того, нові рядки ігноруються, і повідомлення стає усіченим . -u criticalвирішує це.
Дан Даскалеску

Технічно notify-sendне ігнорується час очікування. Саме процес приймає сповіщення як вхід і відображає його над робочим столом, який вирішує ігнорувати час очікування. Дивіться також: unix.stackexchange.com/q/251243/20336
Mikko Rantalainen

1

Оновлена ​​версія сценарію, яка працює з програмою 3.3.10

#!/bin/bash

#Minimum available memory limit, MB
THRESHOLD=400

#Check time interval, sec
INTERVAL=30

while :
do
    free_out=$(free -w -m)
    available=$(awk '/^Mem:/{print $8}' <<<$free_out)

    if (( $available < $THRESHOLD ))
        then
        notify-send -u critical "Memory is running out!" "Available memory is $available MiB"
        echo "Warning - available memory is $available MiB"    
    fi

    cat <<<$free_out
    sleep $INTERVAL
done

1

Оновлений вище сценарій, щоб також додати деталі про топ-3 процесів, які проголошують пам'ять. Дивіться на https://github.com/romanmelko/ubuntu-low-mem-popup

Ось сам сценарій:

#!/usr/bin/env bash

set -o errexit
set -o pipefail
set -o nounset

# If the language is not English, free will output localized text and parsing fails
LANG=en_US.UTF-8

THRESHOLD=500
INTERVAL=300
POPUP_DELAY=999999

# sleep some time so the shell starts properly
sleep 60

while :
do
    available=$(free -mw | awk '/^Mem:/{print $8}')
    if [ $available -lt $THRESHOLD ]; then
        title="Low memory! $available MB available"
        message=$(top -bo %MEM -n 1 | grep -A 3 PID | awk '{print $(NF - 6) " \t" $(NF)}')
        # KDE Plasma notifier
        kdialog --title "$title" --passivepopup "$message" $POPUP_DELAY
        # use the following command if you are not using KDE Plasma, comment the line above and uncomment the line below
        # please note that timeout for notify-send is represented in milliseconds
        # notify-send -u critical "$title" "$message" -t $POPUP_DELAY
    fi
    sleep $INTERVAL
done

Дякую за внесок. Кращою практикою тут є узагальнення (у цьому випадку копії) вмісту посилання, на яке ви посилаєтесь. Таким чином, ваша відповідь залишається дійсною, навіть якщо посилання зникає.
Marc Vanhoomissen

1

Варіант використання доступної оперативної пам’яті , відсотків та відображення сповіщень на робочому столі при виклику cron (тобто сценарій циклу не потрібно запускати після перезавантаження):

#!/usr/bin/env bash

# dbus env var required when called via cron:
eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ | tr '\0' '\n')";

AVAIL_THRESHOLD=5

free_output=$(free)
mem_total=$(awk '/^Mem:/{print $2}' <<< $free_output)
mem_avail=$(awk '/^Mem:/{print $7}' <<< $free_output)
mem_avail_m=$(bc <<< "scale=1; $mem_avail/1024")
percent_avail=$(bc <<< "scale=1; $mem_avail*100 /$mem_total")
should_warn=$(bc <<< "$percent_avail < $AVAIL_THRESHOLD")

if (( $should_warn )); then
    notify-send "Memory warning - only $percent_avail% ($mem_avail_m MB) available"
else
    echo "Memory OK - $percent_avail% ($mem_avail_m MB) available"
fi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.