remove trash
This commit is contained in:
parent
7b5cb79c07
commit
9f438726b4
@ -31,7 +31,6 @@
|
||||
- [x] `oom-sort`
|
||||
- [x] `psi-top`
|
||||
- [x] `psi-monitor`
|
||||
- [x] `i-memhog`
|
||||
- [x] Improve poll rate algorithm
|
||||
- [x] Fixed Makefile for installation on CentOS 7 (remove gzip `-k` option).
|
||||
- [x] Added `max_post_sigterm_victim_lifetime` option: send SIGKILL to the victim if it doesn't respond to SIGTERM for a certain time
|
||||
|
2
Makefile
2
Makefile
@ -12,7 +12,6 @@ install:
|
||||
install -m0755 ./oom-sort $(DESTDIR)/$(PREFIX)/usr/bin/oom-sort
|
||||
install -m0755 ./psi-top $(DESTDIR)/$(PREFIX)/usr/bin/psi-top
|
||||
install -m0755 ./psi-monitor $(DESTDIR)/$(PREFIX)/usr/bin/psi-monitor
|
||||
install -m0755 ./i-memhog $(DESTDIR)/$(PREFIX)/usr/bin/i-memhog
|
||||
|
||||
install -d $(DESTDIR)/$(PREFIX)/etc/nohang
|
||||
-git describe --tags --long --dirty > ./version
|
||||
@ -41,7 +40,6 @@ uninstall:
|
||||
rm -fv $(PREFIX)/usr/bin/oom-sort
|
||||
rm -fv $(PREFIX)/usr/bin/psi-top
|
||||
rm -fv $(PREFIX)/usr/bin/psi-monitor
|
||||
rm -fv $(PREFIX)/usr/bin/i-memhog
|
||||
rm -fv $(PREFIX)/usr/share/man/man1/nohang.1.gz
|
||||
rm -fv $(PREFIX)/usr/share/man/man1/oom-sort.1.gz
|
||||
rm -fv $(PREFIX)/lib/systemd/system/nohang.service
|
||||
|
@ -292,7 +292,7 @@ See also `man journalctl`.
|
||||
You can also enable `separate_log` in the config to logging in `/var/log/nohang/nohang.log`.
|
||||
|
||||
|
||||
## Additional tools: oom-sort, psi-top, psi-monitor, i-memhog
|
||||
## Additional tools: oom-sort, psi-top, psi-monitor
|
||||
|
||||
|
||||
### oom-sort
|
||||
@ -503,10 +503,6 @@ some 0.29 7.58 14.58 | full 0.28 6.92 13.24
|
||||
```
|
||||
</details>
|
||||
|
||||
### i-memhog
|
||||
|
||||
`i-memhog` is an interactive memory hog for testing purposes.
|
||||
|
||||
## Contribution
|
||||
|
||||
Use cases, feature requests and any questions are [welcome](https://github.com/hakavlad/nohang/issues).
|
||||
|
315
i-memhog
315
i-memhog
@ -1,315 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
from signal import signal, SIGTERM
|
||||
from time import sleep
|
||||
from sys import exit
|
||||
import os
|
||||
|
||||
|
||||
# чек общей доступной, для lim2avail
|
||||
def total_mem_available():
|
||||
|
||||
with open('/proc/meminfo') as file:
|
||||
mem_list = file.readlines()
|
||||
|
||||
mem_available = meminfo_num(mem_list, mem_available_index)
|
||||
swap_free = meminfo_num(mem_list, swap_free_index)
|
||||
|
||||
return round((swap_free + mem_available) / 1024) # MiB
|
||||
|
||||
|
||||
# добитие байтами рандома
|
||||
def terminal():
|
||||
ex = []
|
||||
while True:
|
||||
try:
|
||||
ex.append(os.urandom(1))
|
||||
except MemoryError:
|
||||
continue
|
||||
|
||||
|
||||
def meminfo_num(mem_list, index):
|
||||
return int(mem_list[index].split(':')[1].split(' ')[-2])
|
||||
|
||||
|
||||
# выдача основных показателей meminfo, KiB
|
||||
def mem_check_main():
|
||||
|
||||
with open('/proc/meminfo') as file:
|
||||
mem_list = file.readlines()
|
||||
|
||||
mem_available = meminfo_num(mem_list, mem_available_index)
|
||||
swap_total = meminfo_num(mem_list, swap_total_index)
|
||||
swap_free = meminfo_num(mem_list, swap_free_index)
|
||||
|
||||
return mem_available, swap_total, swap_free
|
||||
|
||||
|
||||
def signal_handler(signum, frame):
|
||||
print('Got signal {}'.format(signum))
|
||||
# sleep(1)
|
||||
# exit()
|
||||
|
||||
|
||||
def meminfo():
|
||||
|
||||
# получаем сырой mem_list
|
||||
with open('/proc/meminfo') as file:
|
||||
mem_list = file.readlines()
|
||||
|
||||
# получаем список названий позиций: MemTotal etc
|
||||
mem_list_names = []
|
||||
for s in mem_list:
|
||||
mem_list_names.append(s.split(':')[0])
|
||||
|
||||
# ищем MemAvailable, обрабатываем исключение
|
||||
try:
|
||||
mem_available_index = mem_list_names.index('MemAvailable')
|
||||
except ValueError:
|
||||
print("Your Linux kernel is too old (3.14+ requied), bye!")
|
||||
# исключение для ядер < 3.14, не определяющих MemAvailable
|
||||
exit()
|
||||
|
||||
# ищем позиции SwapTotl и SwapFree
|
||||
swap_total_index = mem_list_names.index('SwapTotal')
|
||||
swap_free_index = mem_list_names.index('SwapFree')
|
||||
|
||||
buffers_index = mem_list_names.index('Buffers')
|
||||
cached_index = mem_list_names.index('Cached')
|
||||
active_index = mem_list_names.index('Active')
|
||||
inactive_index = mem_list_names.index('Inactive')
|
||||
shmem_index = mem_list_names.index('Shmem')
|
||||
|
||||
# ищем значение MemTotal в KiB
|
||||
mem_total = int(mem_list[0].split(':')[1].split(' ')[-2])
|
||||
|
||||
return mem_total, mem_available_index, swap_total_index, swap_free_index, buffers_index, cached_index, active_index, inactive_index, shmem_index
|
||||
|
||||
|
||||
meminfo_tuple = meminfo()
|
||||
|
||||
mem_total = meminfo_tuple[0]
|
||||
mem_available_index = meminfo_tuple[1]
|
||||
swap_total_index = meminfo_tuple[2]
|
||||
swap_free_index = meminfo_tuple[3]
|
||||
|
||||
buffers_index = meminfo_tuple[4]
|
||||
cached_index = meminfo_tuple[5]
|
||||
active_index = meminfo_tuple[6]
|
||||
inactive_index = meminfo_tuple[7]
|
||||
shmem_index = meminfo_tuple[8]
|
||||
|
||||
|
||||
# печать показателей на этапах работы
|
||||
def print_mem():
|
||||
|
||||
mem_tup = mem_check_main()
|
||||
|
||||
mem_available = mem_tup[0]
|
||||
swap_total = mem_tup[1]
|
||||
swap_free = mem_tup[2]
|
||||
|
||||
print(
|
||||
'MemAvailable: ',
|
||||
round(
|
||||
mem_available /
|
||||
1024 /
|
||||
1024,
|
||||
3),
|
||||
'GiB,',
|
||||
round(
|
||||
mem_available /
|
||||
1024),
|
||||
'MiB,',
|
||||
round(
|
||||
mem_available /
|
||||
mem_total *
|
||||
100,
|
||||
1),
|
||||
'%')
|
||||
|
||||
if swap_total != 0:
|
||||
print(
|
||||
'SwapFree: ',
|
||||
round(
|
||||
swap_free /
|
||||
1024 /
|
||||
1024,
|
||||
3),
|
||||
'GiB,',
|
||||
round(
|
||||
swap_free /
|
||||
1024),
|
||||
'MiB,',
|
||||
round(
|
||||
swap_free /
|
||||
swap_total *
|
||||
100,
|
||||
1),
|
||||
'%')
|
||||
print('Total Free: ',
|
||||
round((mem_available + swap_free) / 1024 / 1024,
|
||||
3),
|
||||
'GiB,',
|
||||
round((mem_available + swap_free) / 1024),
|
||||
'MiB,',
|
||||
round((mem_available + swap_free) / (mem_total + swap_total) * 100,
|
||||
1),
|
||||
'%')
|
||||
else:
|
||||
print(
|
||||
'Swap disabled'
|
||||
)
|
||||
|
||||
|
||||
# бесконечный жор
|
||||
def inf():
|
||||
|
||||
print(
|
||||
'Вводите целые неотрицательные числа. Чем больше, тем быстрее потребление памяти.\n1000 same обеспечивает потребление на уровне полтора гиг в секунду,\nurandom работает на скорости максимум 170 M/s'
|
||||
)
|
||||
same = input("same: ")
|
||||
urandom = input("urandom: ")
|
||||
|
||||
expanding_list = []
|
||||
|
||||
print(
|
||||
'Процесс неограниченного потребления пошёл... Press Ctrl + C for exit'
|
||||
)
|
||||
|
||||
while True:
|
||||
try:
|
||||
expanding_list.append(os.urandom(int(urandom)))
|
||||
expanding_list.append('#' * int(same))
|
||||
except MemoryError:
|
||||
print('MemoryError, start побайтовая добивалка!')
|
||||
terminal()
|
||||
|
||||
|
||||
def selfterm():
|
||||
os.kill(os.getpid(), signal.SIGTERM)
|
||||
|
||||
|
||||
# жор числп гиг
|
||||
def lim():
|
||||
|
||||
expanding_list = []
|
||||
|
||||
n = input('На сколько гигабайт уменьшить доступную память?\n: ')
|
||||
|
||||
print('Погнали тратить ' + n + ' гиг...')
|
||||
|
||||
i = 0
|
||||
|
||||
while True:
|
||||
|
||||
i += 1
|
||||
|
||||
try:
|
||||
expanding_list.append(os.urandom(int(100)))
|
||||
expanding_list.append('#' * int(300))
|
||||
except MemoryError:
|
||||
print('MemoryError!')
|
||||
break
|
||||
if i > 2020202 * int(n):
|
||||
print('DONE')
|
||||
break
|
||||
|
||||
return expanding_list
|
||||
|
||||
|
||||
# жор до остатка мегабайт
|
||||
def lim2avail():
|
||||
|
||||
expanding_list = []
|
||||
|
||||
n = input(
|
||||
'Сколько мегабайт общей доступной памяти (MemAvailable + SwapFree) оставить?\nВведите целое положительное число: '
|
||||
)
|
||||
|
||||
# проверка на целое положительное
|
||||
if n.isdigit():
|
||||
n = int(n)
|
||||
else:
|
||||
print(
|
||||
'Вы ввели не целое положительное число'
|
||||
)
|
||||
return 0
|
||||
|
||||
if n == 0:
|
||||
print(
|
||||
'Вы ввели не целое положительное число'
|
||||
)
|
||||
return 0
|
||||
|
||||
print(
|
||||
'Погнали уменьшать доступную память до уровня ниже ' +
|
||||
str(n) +
|
||||
' MiB...')
|
||||
|
||||
while True:
|
||||
try:
|
||||
expanding_list.append(os.urandom(5000))
|
||||
expanding_list.append('#' * 5000)
|
||||
except MemoryError:
|
||||
print('MemoryError!')
|
||||
break
|
||||
if total_mem_available() <= n:
|
||||
print('DONE')
|
||||
break
|
||||
|
||||
return expanding_list
|
||||
|
||||
|
||||
print('WARNING: эта прога способна потратить память и повесить систему, будьте осторожны.')
|
||||
print('При ее работе следите за показателями памяти.')
|
||||
|
||||
|
||||
print('Ignore SIGTERM? (y|n)')
|
||||
|
||||
sss = input(': ')
|
||||
|
||||
if sss == 'y':
|
||||
signal(SIGTERM, signal_handler)
|
||||
print('The SIGTERM signal will be ignored')
|
||||
else:
|
||||
print('The SIGTERM signal will NOT be ignored')
|
||||
|
||||
|
||||
ex_list = []
|
||||
|
||||
try:
|
||||
while True:
|
||||
|
||||
print()
|
||||
print_mem()
|
||||
print()
|
||||
print('Выберите вариант из списка ниже')
|
||||
print('8 или i или I - запустить бесконечное потребление, предложив выбрать скорость потребления и энтропию')
|
||||
print('7 или l или L - запустить ограниченное потребление заданного числа гигов')
|
||||
print('6 или a или A - жрать память пока количество доступной памяти не опустится ниже заданного')
|
||||
print('0 или с или С - очистить накопления при их наличии')
|
||||
print('q или любой другой символ - выход (можно просто нажать Enter)')
|
||||
|
||||
li = input(': ')
|
||||
|
||||
if li is 'l' or li is 'L' or li is '7':
|
||||
x = lim()
|
||||
ex_list.append(x)
|
||||
elif li is 'i' or li is 'I' or li is '8':
|
||||
inf()
|
||||
elif li is 'c' or li is 'C' or li is '0':
|
||||
ex_list = []
|
||||
x = 0
|
||||
y = 0
|
||||
elif li is '6' or li is 'a' or li is 'A':
|
||||
y = lim2avail()
|
||||
ex_list.append(y)
|
||||
else:
|
||||
exit()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
print_mem()
|
||||
selfterm()
|
@ -1,46 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Fedora 21 (KDE) Гуглил долго, про oom-killer много чего прочитал. Но не понял, как его активировать. whereis его не нашёл, в репах его не нашёл. Если это встроенное средство - почему у меня не запускается и где его конфиг? Мне нужно тупо, чтобы если оперативка исчерпалась - прибило последнюю вкладку хрома. Либо вообще killall chrome тупо и всё. Как проще всего сделать?
|
||||
https://www.linux.org.ru/forum/desktop/11511840
|
||||
|
||||
|
||||
|
||||
OOM Killer под себя
|
||||
|
||||
Здравствуйте!
|
||||
Задача такова, надо (курсовая работа по системному программированию) пропатчить ядро с изменением oom killer'a, т.е.
|
||||
1)требуется создать некоторый список с названиями процессов, которые "мудрый киллер" будет удалять в первую очередь или наоборот оставлять.
|
||||
2)требуется создать свою систему расчета приоритетов для удаления процессов.
|
||||
Я НЕ продвинутый линуксоид, поэтому прошу помощи у общественности. С чего начать и как приступить к выполнению?
|
||||
https://www.linux.org.ru/forum/development/3555574
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Товарищи, можете посоветовать какую-нибудь стандартную программу, которая, в какой-то определённо ситуации, жрала память, что приводило бы к запуску Killer`a.
|
||||
Чтобы потом можно было на ней тестить курсач)
|
||||
https://www.linux.org.ru/forum/development/3555574?cid=3570489
|
||||
|
||||
|
||||
Post-mortem по логам OOM-killer.
|
||||
Суть такова, в определенный момент на машине случилось нечто, в результате чего кончилась физическая память и ОС залезла в своп с головой. Производительность упала до потери всякого отклика от машины. OOM-killer включился, но, похоже, занимался убийством исключительно невиновных и никому не мешающих процессов.
|
||||
Можно ли как-то по логам отследить, кто сожрал всю память? Хотя бы имена павших жертвами киллера?
|
||||
Или сразу самому писать скрипт, сбрасывающий на диск ps aux, для следующего такого случая?
|
||||
https://www.linux.org.ru/forum/admin/5693261
|
||||
|
||||
|
||||
Проблема в том что у меня на VDS мало оперативки и она занята полностью пытаясь подключиться сервер не может выделить памяти и обрывает соединение. что прописать чтобы ссх постоянно висел в процессах с выделенным скажем полумегабайтным или сколько там ему достаточно лимитом?
|
||||
https://www.linux.org.ru/forum/general/5399920?cid=5399954
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check file for non-ascii lines."""
|
||||
|
||||
from sys import argv
|
||||
|
||||
path = argv[1]
|
||||
|
||||
print('Path:', path)
|
||||
|
||||
|
||||
def isascii(string):
|
||||
try:
|
||||
string_ascii = string.encode('ascii')
|
||||
return True
|
||||
except UnicodeEncodeError:
|
||||
return False
|
||||
|
||||
|
||||
def check_file():
|
||||
num = 0
|
||||
with open(path) as f:
|
||||
for n, line in enumerate(f):
|
||||
res = isascii(line)
|
||||
if res:
|
||||
continue
|
||||
else:
|
||||
print('Line {} is non-ascii:'.format(n + 1))
|
||||
print(line.strip('\n'))
|
||||
num += 1
|
||||
continue
|
||||
print('Found {} non-ascii lines'.format(num))
|
||||
|
||||
|
||||
check_file()
|
276
trash/memco.py
276
trash/memco.py
@ -1,276 +0,0 @@
|
||||
# memdler common
|
||||
|
||||
import os
|
||||
import glob
|
||||
import signal
|
||||
import subprocess
|
||||
from glob import glob
|
||||
from time import sleep
|
||||
|
||||
|
||||
# k = mem_total_used / (zram own size)
|
||||
k = 0.0042
|
||||
|
||||
|
||||
def meminfo():
|
||||
|
||||
# получаем сырой mem_list
|
||||
with open('/proc/meminfo') as file:
|
||||
mem_list = file.readlines()
|
||||
|
||||
# получаем список названий позиций: MemTotal etc
|
||||
mem_list_names = []
|
||||
for s in mem_list:
|
||||
mem_list_names.append(s.split(':')[0])
|
||||
|
||||
# ищем MemAvailable, обрабатываем исключение
|
||||
try:
|
||||
mem_available_index = mem_list_names.index('MemAvailable')
|
||||
except ValueError:
|
||||
print("Your Linux kernel is too old (3.14+ requied), bye!")
|
||||
# исключение для ядер < 3.14, не определяющих MemAvailable
|
||||
exit()
|
||||
|
||||
# ищем позиции SwapTotl и SwapFree
|
||||
swap_total_index = mem_list_names.index('SwapTotal')
|
||||
swap_free_index = mem_list_names.index('SwapFree')
|
||||
|
||||
buffers_index = mem_list_names.index('Buffers')
|
||||
cached_index = mem_list_names.index('Cached')
|
||||
active_index = mem_list_names.index('Active')
|
||||
inactive_index = mem_list_names.index('Inactive')
|
||||
shmem_index = mem_list_names.index('Shmem')
|
||||
|
||||
# ищем значение MemTotal в KiB
|
||||
mem_total = int(mem_list[0].split(':')[1].split(' ')[-2])
|
||||
|
||||
return mem_total, mem_available_index, swap_total_index, swap_free_index, buffers_index, cached_index, active_index, inactive_index, shmem_index
|
||||
|
||||
|
||||
meminfo_tuple = meminfo()
|
||||
|
||||
mem_total = meminfo_tuple[0]
|
||||
mem_available_index = meminfo_tuple[1]
|
||||
swap_total_index = meminfo_tuple[2]
|
||||
swap_free_index = meminfo_tuple[3]
|
||||
|
||||
buffers_index = meminfo_tuple[4]
|
||||
cached_index = meminfo_tuple[5]
|
||||
active_index = meminfo_tuple[6]
|
||||
inactive_index = meminfo_tuple[7]
|
||||
shmem_index = meminfo_tuple[8]
|
||||
|
||||
|
||||
def meminfo_num(mem_list, index):
|
||||
return int(mem_list[index].split(':')[1].split(' ')[-2])
|
||||
|
||||
|
||||
# выдача основных показателей meminfo, KiB
|
||||
def mem_check_main():
|
||||
|
||||
with open('/proc/meminfo') as file:
|
||||
mem_list = file.readlines()
|
||||
|
||||
mem_available = meminfo_num(mem_list, mem_available_index)
|
||||
swap_total = meminfo_num(mem_list, swap_total_index)
|
||||
swap_free = meminfo_num(mem_list, swap_free_index)
|
||||
|
||||
return mem_available, swap_total, swap_free
|
||||
|
||||
|
||||
# читать не весь файл, а нужный срез от 0 до 20, например
|
||||
def mem_check_full():
|
||||
|
||||
with open('/proc/meminfo') as file:
|
||||
mem_list = file.readlines()
|
||||
|
||||
mem_available = meminfo_num(mem_list, mem_available_index)
|
||||
swap_total = meminfo_num(mem_list, swap_total_index)
|
||||
swap_free = meminfo_num(mem_list, swap_free_index)
|
||||
|
||||
buffers = meminfo_num(mem_list, buffers_index)
|
||||
cached = meminfo_num(mem_list, cached_index)
|
||||
active = meminfo_num(mem_list, active_index)
|
||||
inactive = meminfo_num(mem_list, inactive_index)
|
||||
shmem = meminfo_num(mem_list, shmem_index)
|
||||
|
||||
return mem_available, swap_total, swap_free, buffers, cached, active, inactive, shmem
|
||||
|
||||
|
||||
# чек общей доступной, для lim2avail
|
||||
def total_mem_available():
|
||||
|
||||
with open('/proc/meminfo') as file:
|
||||
mem_list = file.readlines()
|
||||
|
||||
mem_available = meminfo_num(mem_list, mem_available_index)
|
||||
swap_free = meminfo_num(mem_list, swap_free_index)
|
||||
|
||||
return round((swap_free + mem_available) / 1024) # MiB
|
||||
|
||||
|
||||
# добитие байтами рандома
|
||||
def terminal():
|
||||
ex = []
|
||||
while True:
|
||||
try:
|
||||
ex.append(os.urandom(1))
|
||||
except MemoryError:
|
||||
continue
|
||||
|
||||
|
||||
# перевод дроби в проценты
|
||||
def percent(num):
|
||||
a = str(round(num * 100, 1)).split('.')
|
||||
a0 = a[0].rjust(3, ' ')
|
||||
a1 = a[1]
|
||||
return '{}.{}'.format(a0, a1)
|
||||
|
||||
|
||||
def human(num):
|
||||
return str(round(num / 1024.0)).rjust(8, ' ')
|
||||
|
||||
|
||||
|
||||
# B -> GiB
|
||||
def humanz(num):
|
||||
a = str(round(num / 1073741824, 3))
|
||||
a0 = a.split('.')[0].rjust(4, ' ')
|
||||
a1 = a.split('.')[1]
|
||||
if len(a1) == 1:
|
||||
a1 += '00'
|
||||
if len(a1) == 2:
|
||||
a1 += '0'
|
||||
return '{}.{}'.format(a0, a1)
|
||||
|
||||
|
||||
|
||||
movie_dict = {
|
||||
'+----': '-+---',
|
||||
'-+---': '--+--',
|
||||
'--+--': '---+-',
|
||||
'---+-': '----+',
|
||||
'----+': '+----'
|
||||
}
|
||||
|
||||
|
||||
def config_parser(config):
|
||||
if os.path.exists(config):
|
||||
try:
|
||||
with open(config) as f:
|
||||
name_value_dict = dict()
|
||||
for line in f:
|
||||
a = line.startswith('#')
|
||||
b = line.startswith('\n')
|
||||
c = line.startswith('\t')
|
||||
d = line.startswith(' ')
|
||||
if not a and not b and not c and not d:
|
||||
a = line.split('=')
|
||||
name_value_dict[a[0].strip()] = a[1].strip()
|
||||
return name_value_dict
|
||||
except PermissionError:
|
||||
print('config: permission error')
|
||||
else:
|
||||
print('config does not exists')
|
||||
|
||||
|
||||
|
||||
|
||||
def swaps_raw(part_string):
|
||||
'''анализ строки свопс, возврат кортежа с значениями'''
|
||||
part_string_list = part_string.split('\t')
|
||||
part_name = part_string_list[0].split(' ')[0]
|
||||
|
||||
part_size = int(part_string_list[-3])
|
||||
part_used = int(part_string_list[-2])
|
||||
part_prio = int(part_string_list[-1])
|
||||
|
||||
return part_name, part_size, part_used, part_prio
|
||||
|
||||
|
||||
|
||||
# возвращает disksize и mem_used_total по zram id
|
||||
def zram_stat(zram_id):
|
||||
with open('/sys/block/zram' + zram_id + '/disksize') as file:
|
||||
disksize = file.readlines()[0][:-1]
|
||||
if os.path.exists('/sys/block/zram' + zram_id + '/mm_stat'):
|
||||
with open('/sys/block/zram' + zram_id + '/mm_stat') as file:
|
||||
mm_stat = file.readlines()[0][:-1].split(' ')
|
||||
mm_stat_list = []
|
||||
for i in mm_stat:
|
||||
if i != '':
|
||||
mm_stat_list.append(i)
|
||||
mem_used_total = mm_stat_list[2]
|
||||
else:
|
||||
with open('/sys/block/zram' + zram_id + '/mem_used_total') as file:
|
||||
mem_used_total = file.readlines()[0][:-1]
|
||||
return disksize, mem_used_total
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# termer(signal.SIGKILL)
|
||||
# process terminator
|
||||
# функция поиска жиробаса и его убийства
|
||||
def terminator(signal):
|
||||
|
||||
subdirs = glob('/proc/*/')
|
||||
subdirs.remove('/proc/self/')
|
||||
subdirs.remove('/proc/thread-self/')
|
||||
|
||||
pid_list = []
|
||||
name_list = []
|
||||
oom_score_list = []
|
||||
|
||||
for subdir in subdirs:
|
||||
|
||||
try:
|
||||
|
||||
with open(subdir + 'status') as file:
|
||||
status = file.readlines()
|
||||
|
||||
pid_list.append(status[5].split(':')[1][1:-1])
|
||||
name_list.append(status[0].split(':')[1][1:-1])
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
|
||||
with open(subdir + 'oom_score') as file:
|
||||
oom_score = file.readlines()
|
||||
|
||||
oom_score_list.append(int(oom_score[0][0:-1]))
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
max_oom_score = sorted(oom_score_list)[-1]
|
||||
n = oom_score_list.index(max_oom_score)
|
||||
s = sorted(oom_score_list)
|
||||
s.reverse()
|
||||
|
||||
if signal == signal.SIGTERM:
|
||||
print('\nTRY TO TERM {}, Pid {}\n'.format(name_list[n], pid_list[n]))
|
||||
else:
|
||||
print('\nTRY TO KILL {}, Pid {}\n'.format(name_list[n], pid_list[n]))
|
||||
|
||||
try:
|
||||
os.kill(int(pid_list[n]), signal)
|
||||
except ProcessLookupError:
|
||||
print('No such process')
|
||||
|
||||
|
||||
|
||||
|
||||
def selfterm():
|
||||
os.kill(os.getpid(), signal.SIGTERM)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
cp ./memleak /usr/sbin/memleak
|
||||
cp ./memleak.service /lib/systemd/system/memleak.service
|
||||
systemctl daemon-reload
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from os import system
|
||||
from time import sleep
|
||||
|
||||
x = []
|
||||
|
||||
while True:
|
||||
x.append('#' * 99999)
|
||||
sleep(0.1)
|
||||
system('sleep 9999 &')
|
||||
|
@ -1,9 +0,0 @@
|
||||
[Unit]
|
||||
Description=Memory leak daemon
|
||||
After=sysinit.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/sbin/memleak
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
315
trash/mm
315
trash/mm
@ -1,315 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# ms-monitor/
|
||||
|
||||
from memco import *
|
||||
import time
|
||||
|
||||
# once or 1, log or 2, inplace or 3
|
||||
mode = '3'
|
||||
|
||||
# период цикла печати
|
||||
period = 0.2
|
||||
|
||||
# параметры визуализации
|
||||
used = '$'
|
||||
free = '~'
|
||||
len_visual = 14
|
||||
|
||||
# нахождение и печать параметров, возвращает показатели и принимает показатели для нахождения дельт
|
||||
def printer(old_list):
|
||||
|
||||
mem_tup = mem_check_main()
|
||||
|
||||
mem_available = mem_tup[0]
|
||||
swap_total = mem_tup[1]
|
||||
swap_free = mem_tup[2]
|
||||
|
||||
tn = time.time()
|
||||
delta = tn - old_list[4]
|
||||
|
||||
mem_busy = mem_total - mem_available
|
||||
swap_busy = swap_total - swap_free
|
||||
|
||||
mem_swap_total = mem_total + swap_total
|
||||
mem_swap_free = mem_available + swap_free
|
||||
mem_swap_busy = mem_busy + swap_busy
|
||||
|
||||
delta_mem = (mem_busy - old_list[0]) / delta
|
||||
delta_swap = (swap_busy - old_list[1]) / delta
|
||||
delta_all = (mem_swap_busy - old_list[2]) / delta
|
||||
|
||||
if swap_total == 0:
|
||||
|
||||
#1###################################################################################
|
||||
|
||||
# печать без свопа
|
||||
|
||||
mem_visual = (
|
||||
used * round(mem_busy / mem_total * len_visual)
|
||||
).ljust(len_visual, free)
|
||||
|
||||
print(
|
||||
' MEM'
|
||||
)
|
||||
|
||||
print(
|
||||
'TOTAL {}'.format(
|
||||
human(mem_total),
|
||||
)
|
||||
)
|
||||
print(
|
||||
'N/A {} {}'.format(
|
||||
human(mem_busy),
|
||||
percent(mem_busy / mem_total),
|
||||
)
|
||||
)
|
||||
print(
|
||||
'AVAIL {} {}'.format(
|
||||
human(mem_available),
|
||||
percent(mem_available / mem_total),
|
||||
)
|
||||
)
|
||||
print(
|
||||
'DELTA {}'.format(
|
||||
human(delta_mem),
|
||||
)
|
||||
)
|
||||
print(
|
||||
'{} {}'.format(
|
||||
old_list[3], mem_visual
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
#2###################################################################################
|
||||
|
||||
else:
|
||||
|
||||
with open('/proc/swaps') as file:
|
||||
swaps_list = file.readlines()[1:]
|
||||
|
||||
zram_id_list = []
|
||||
|
||||
disk_swap_size = 0
|
||||
disk_swap_used = 0
|
||||
zram_swap_size = 0
|
||||
zram_swap_used = 0
|
||||
|
||||
for i in swaps_list:
|
||||
|
||||
x = swaps_raw(i)
|
||||
|
||||
if x[0].startswith('/dev/zram'):
|
||||
|
||||
zram_swap_size += int(x[1])
|
||||
zram_swap_used += int(x[2])
|
||||
|
||||
zram_id_list.append(x[0][9:])
|
||||
|
||||
else:
|
||||
|
||||
disk_swap_size += int(x[1])
|
||||
disk_swap_used += int(x[2])
|
||||
|
||||
if zram_swap_size == 0:
|
||||
|
||||
#3###################################################################################
|
||||
|
||||
# печать своп без зрам
|
||||
|
||||
mem_visual = (
|
||||
used * round(mem_busy / mem_total * len_visual)
|
||||
).ljust(len_visual, free)
|
||||
swap_visual = (
|
||||
used * round(swap_busy / swap_total * len_visual)
|
||||
).ljust(len_visual, free)
|
||||
mem_swap_visual = (
|
||||
used * round(mem_swap_busy / mem_swap_total * len_visual)
|
||||
).ljust(len_visual, free)
|
||||
|
||||
print(
|
||||
' MEM SWAP MEM + SWAP'
|
||||
)
|
||||
|
||||
print(
|
||||
'TOTAL {} {} {}'.format(
|
||||
human(mem_total),
|
||||
human(swap_total),
|
||||
human(mem_swap_total),
|
||||
)
|
||||
)
|
||||
print(
|
||||
'N/A {} {} {} {} {} {}'.format(
|
||||
human(mem_busy),
|
||||
percent(mem_busy / mem_total),
|
||||
human(swap_busy),
|
||||
percent(swap_busy / swap_total),
|
||||
human(mem_swap_busy),
|
||||
percent(mem_swap_busy / mem_swap_total),
|
||||
)
|
||||
)
|
||||
print(
|
||||
'AVAIL {} {} {} {} {} {}'.format(
|
||||
human(mem_available),
|
||||
percent(mem_available / mem_total),
|
||||
human(swap_free),
|
||||
percent(swap_free / swap_total),
|
||||
human(mem_swap_free),
|
||||
percent(mem_swap_free / mem_swap_total),
|
||||
)
|
||||
)
|
||||
print(
|
||||
'DELTA {} {} {}'.format(
|
||||
human(delta_mem),
|
||||
human(delta_swap),
|
||||
human(delta_all)
|
||||
)
|
||||
)
|
||||
print(
|
||||
'{} {} {} {}'.format(
|
||||
old_list[3],
|
||||
mem_visual,
|
||||
swap_visual,
|
||||
mem_swap_visual,
|
||||
)
|
||||
)
|
||||
print()
|
||||
|
||||
#4###################################################################################
|
||||
|
||||
else:
|
||||
|
||||
# суммируем показатели из всех свопов в зрам
|
||||
|
||||
disksize_sum = 0
|
||||
mem_used_total_sum = 0
|
||||
|
||||
for i in zram_id_list:
|
||||
s = zram_stat(i) # кортеж из disksize и mem_used_total для данного zram id
|
||||
disksize_sum += int(s[0])
|
||||
mem_used_total_sum += int(s[1])
|
||||
|
||||
# находим показатели для ZRAM
|
||||
full = disksize_sum * k + mem_used_total_sum
|
||||
profit = zram_swap_used - (full / 1024)
|
||||
cr_real = round(zram_swap_used * 1024 / mem_used_total_sum, 2)
|
||||
|
||||
#5###################################################################################
|
||||
|
||||
# печать своп + зрам
|
||||
|
||||
mem_visual = (
|
||||
used * round(mem_busy / mem_total * len_visual)
|
||||
).ljust(len_visual, free)
|
||||
swap_visual = (
|
||||
used * round(swap_busy / swap_total * len_visual)
|
||||
).ljust(len_visual, free)
|
||||
mem_swap_visual = (
|
||||
used * round(mem_swap_busy / mem_swap_total * len_visual)
|
||||
).ljust(len_visual, free)
|
||||
zram_visual = (
|
||||
used * round(full / 1024 / mem_total * 18)
|
||||
).ljust(18, free)
|
||||
|
||||
print(
|
||||
' MEM SWAP MEM + SWAP ZRAM SWAP'
|
||||
)
|
||||
|
||||
print(
|
||||
'TOTAL {} {} {} PROFIT {} M'.format(
|
||||
human(mem_total),
|
||||
human(swap_total),
|
||||
human(mem_swap_total),
|
||||
human(profit)
|
||||
)
|
||||
)
|
||||
print(
|
||||
'N/A {} {} {} {} {} {} CR {}'.format(
|
||||
human(mem_busy),
|
||||
percent(mem_busy / mem_total),
|
||||
human(swap_busy),
|
||||
percent(swap_busy / swap_total),
|
||||
human(mem_swap_busy),
|
||||
percent(mem_swap_busy / mem_swap_total),
|
||||
str(cr_real).rjust(7, ' ')
|
||||
)
|
||||
)
|
||||
print(
|
||||
'AVAIL {} {} {} {} {} {} FULL/MT {} %'.format(
|
||||
human(mem_available),
|
||||
percent(mem_available / mem_total),
|
||||
human(swap_free),
|
||||
percent(swap_free / swap_total),
|
||||
human(mem_swap_free),
|
||||
percent(mem_swap_free / mem_swap_total),
|
||||
percent(full / 1024 / mem_total)
|
||||
)
|
||||
)
|
||||
print(
|
||||
'DELTA {} {} {}'.format(
|
||||
human(delta_mem),
|
||||
human(delta_swap),
|
||||
human(delta_all)
|
||||
)
|
||||
)
|
||||
print(
|
||||
'{} {} {} {} {}'.format(
|
||||
old_list[3],
|
||||
mem_visual,
|
||||
swap_visual,
|
||||
mem_swap_visual,
|
||||
zram_visual
|
||||
)
|
||||
)
|
||||
print()
|
||||
|
||||
#6###################################################################################
|
||||
|
||||
# печать по партициям
|
||||
|
||||
print('FILENAME USED SIZE PRIORITY')
|
||||
|
||||
for i in swaps_list:
|
||||
x = swaps_raw(i)
|
||||
print(
|
||||
'{} {} G {} % {} G {}'.format(
|
||||
str(x[0]).ljust(26, ' '),
|
||||
human(x[2]),
|
||||
percent(x[2] / x[1]), human(x[1]),
|
||||
str(x[3]).rjust(10, ' ')
|
||||
)
|
||||
)
|
||||
|
||||
return [mem_busy, swap_busy, mem_swap_busy, movie_dict[(old_list[3])], tn]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
|
||||
delta = [0, 0, 0, '+----', 0]
|
||||
|
||||
if mode == 'log' or mode == '2':
|
||||
|
||||
while True:
|
||||
delta = printer(delta)
|
||||
sleep(period)
|
||||
|
||||
elif mode == 'inplace' or mode == '3':
|
||||
|
||||
while True:
|
||||
print("\033c")
|
||||
delta = printer(delta)
|
||||
sleep(period)
|
||||
|
||||
else:
|
||||
|
||||
delta = printer(delta)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
exit()
|
||||
|
140
trash/new5.conf
140
trash/new5.conf
@ -1,140 +0,0 @@
|
||||
This is nohang config file.
|
||||
Lines starting with $ contain obligatory parameters.
|
||||
Lines starting with @ contain optional parameters.
|
||||
Other lines are comments.
|
||||
|
||||
0. Common zram settings
|
||||
|
||||
See https://www.kernel.org/doc/Documentation/blockdev/zram.txt
|
||||
You maybe need $IGNORE_ZRAM=FALSE if you has a big zram disksize
|
||||
|
||||
$IGNORE_ZRAM = TRUE
|
||||
|
||||
1. Common PSI settings
|
||||
|
||||
See
|
||||
https://lwn.net/Articles/759658/
|
||||
https://facebookmicrosites.github.io/psi/
|
||||
|
||||
$IGNORE_PSI = TRUE
|
||||
|
||||
$PSI_PATH = /proc/pressure/memory
|
||||
|
||||
some_avg10 is most sensitive.
|
||||
|
||||
$PSI_METRICS = some_avg10
|
||||
|
||||
$PSI_EXCESS_DURATION = 0
|
||||
|
||||
$PSI_POST_ACTION_DELAY = 40
|
||||
|
||||
|
||||
|
||||
2. Poll rate
|
||||
|
||||
$FILL_RATE_MEM = 4000
|
||||
$FILL_RATE_SWAP = 1500
|
||||
$FILL_RATE_ZRAM = 500
|
||||
$MIN_SLEEP = 0.1
|
||||
$MAX_SLEEP = 3
|
||||
|
||||
|
||||
3. Warnings / GUI notifications
|
||||
|
||||
$GUI_CORRECTIVE_ACTIONS = FALSE
|
||||
|
||||
$GUI_LOW_MEMORY_WARNINGS = FALSE
|
||||
$GUI_WARNINGS_MIN_MEM = 20 %
|
||||
$GUI_WARNINGS_MIN_SWAP = 20 %
|
||||
$GUI_WARNINGS_MAX_ZRAM = 45 %
|
||||
$GUI_MIN_DELAY_AFTER_WARNING = 15
|
||||
|
||||
@EXE_INSTEAD_OF_GUI_WARNING wall -n "LOW MEMORY!"
|
||||
@EXE_INSTEAD_OF_GUI_WARNING echo 'test'
|
||||
|
||||
|
||||
4. Soft threshold / SIGTERM-related parameters
|
||||
|
||||
$SOFT_MIN_MEM_THRESHOLD = 10 %
|
||||
$SOFT_MIN_SWAP_THRESHOLD = 10 %
|
||||
$SOFT_MAX_ZRAM_THRESHOLD = 50 %
|
||||
|
||||
$SOFT_POST_ACTION_DELAY = 0.2
|
||||
|
||||
$MAX_POST_SOFT_ACTION_VICTIM_LIFETIME = 9
|
||||
|
||||
$SOFT_MAX_PSI_THRESHOLD = 60
|
||||
$SOFT_MAX_PSI_DURATION = 5
|
||||
|
||||
The execution of specified command instead of sending the SIGTERM signal.
|
||||
Syntax example:
|
||||
<key> <regular expression> /// <command>
|
||||
|
||||
@EXE_INSTEAD_OF_SIGTERM_RE_NAME ^foo$ /// kill -9 $PID && echo "Praise KEK, kill $NAME" &
|
||||
|
||||
@EXE_INSTEAD_OF_SIGTERM_RE_CMDLINE ^/sbin/foo /// systemctl restart foo
|
||||
|
||||
@EXE_INSTEAD_OF_SIGTERM_RE_REALPATH ^/sbin/bar$ /// systemctl restart foo
|
||||
|
||||
@EXE_INSTEAD_OF_SIGTERM_RE_UID ^1000$ /// pkill -SEGV $NAME
|
||||
@EXE_INSTEAD_OF_SIGTERM_RE_UID ^1001$ /// pkill -HUP $NAME
|
||||
|
||||
@SOFT_THRESHOLD_EXE_RE_NAME
|
||||
|
||||
5. Hard threshold / SIGKILL-related parameters
|
||||
|
||||
$HARD_MIN_MEM_THRESHOLD = 5 %
|
||||
$HARD_MIN_SWAP_THRESHOLD = 5 %
|
||||
$HARD_MAX_ZRAM_THRESHOLD = 55 %
|
||||
|
||||
$POST_KILL_EXE =
|
||||
|
||||
$HARD_POST_ACTION_DELAY = 1
|
||||
|
||||
$HARD_MAX_PSI_THRESHOLD = 90
|
||||
$HARD_MAX_PSI_DURATION = 5
|
||||
|
||||
|
||||
$POST_KILL_EXE =
|
||||
|
||||
|
||||
|
||||
6. Adjusting badness of processes
|
||||
|
||||
$OOM_SCORE_ADJ_LIMIT = -1
|
||||
|
||||
Badness adjusting by matching process name, cmdline and eUID with specified regular expression.
|
||||
|
||||
Example badness adj rules
|
||||
<key> <regular expression> /// <badness_adj>
|
||||
|
||||
@BADNESS_ADJ_RE_CMDLINE -childID|--type=renderer /// 200
|
||||
|
||||
@BADNESS_ADJ_RE_NAME ^Xorg$ /// -100
|
||||
|
||||
@BADNESS_ADJ_RE_UID ^0$ /// -50
|
||||
|
||||
@BADNESS_ADJ_RE_REALPATH ^/usr/bin/tail$ /// 100
|
||||
|
||||
|
||||
|
||||
7. Avoid killing small processes (innocent victims)
|
||||
|
||||
$MIN_VICTIM_BADNESS = 20
|
||||
|
||||
|
||||
8. Verbosity
|
||||
|
||||
$PRINT_CONFIG_AT_STARTUP = FALSE // --print-config
|
||||
|
||||
$MIN_MEM_REPORT_INTERVAL = -1
|
||||
|
||||
$PRINT_VICTIM_INFO = TRUE
|
||||
|
||||
$PRINT_TOTAL_STAT = TRUE
|
||||
|
||||
$PRINT_PROC_TABLE = FALSE
|
||||
|
||||
$PRINT_SLEEP_PERIODS = FALSE
|
||||
|
||||
|
2946
trash/nohang 0.2 rc1
2946
trash/nohang 0.2 rc1
File diff suppressed because it is too large
Load Diff
@ -1,427 +0,0 @@
|
||||
|
||||
This is nohang config file.
|
||||
|
||||
Redesign of this config in progress.
|
||||
|
||||
Lines starting with #, tabs and spaces are comments.
|
||||
|
||||
Lines starting with $ contain obligatory parameters.
|
||||
|
||||
Lines starting with @ contain optional parameters.
|
||||
|
||||
The configuration includes the following sections:
|
||||
|
||||
1. Memory levels to respond to as an OOM threat
|
||||
2. Response on PSI memory metrics
|
||||
3. The frequency of checking the level of available memory
|
||||
(and CPU usage)
|
||||
4. The prevention of killing innocent victims
|
||||
5. Impact on the badness of processes via matching their
|
||||
- names,
|
||||
- cmdlines and
|
||||
- UIDs
|
||||
with regular expressions
|
||||
6. The execution of a specific command instead of sending the
|
||||
SIGTERM signal
|
||||
7. GUI notifications:
|
||||
- OOM prevention results and
|
||||
- low memory warnings
|
||||
8. Output verbosity
|
||||
9. Misc
|
||||
|
||||
Just read the description of the parameters and edit the values.
|
||||
Please restart the program after editing the config.
|
||||
|
||||
#####################################################################
|
||||
|
||||
1. Thresholds below which a signal should be sent to the victim
|
||||
|
||||
Sets the available memory levels at or below which SIGTERM or SIGKILL
|
||||
signals are sent. The signal will be sent if MemAvailable and
|
||||
SwapFree (in /proc/meminfo) at the same time will drop below the
|
||||
corresponding values. Can be specified in % (percent) and M (MiB).
|
||||
Valid values are floating-point numbers from the range [0; 100] %.
|
||||
|
||||
MemAvailable levels.
|
||||
|
||||
mem_min_sigterm = 10 %
|
||||
mem_min_sigkill = 5 %
|
||||
|
||||
SwapFree levels.
|
||||
|
||||
swap_min_sigterm = 10 %
|
||||
swap_min_sigkill = 5 %
|
||||
|
||||
Specifying the total share of zram in memory, if exceeded the
|
||||
corresponding signals are sent. As the share of zram in memory
|
||||
increases, it may fall responsiveness of the system. 90 % is a
|
||||
usual hang level, not recommended to set very high.
|
||||
|
||||
Can be specified in % and M. Valid values are floating-point
|
||||
numbers from the range [0; 90] %.
|
||||
|
||||
zram_max_sigterm = 50 %
|
||||
zram_max_sigkill = 55 %
|
||||
|
||||
#####################################################################
|
||||
|
||||
2. Response on PSI memory metrics (it needs Linux 4.20 and up)
|
||||
|
||||
About PSI:
|
||||
https://facebookmicrosites.github.io/psi/
|
||||
|
||||
Disabled by default (ignore_psi = True).
|
||||
|
||||
ignore_psi = True
|
||||
|
||||
Choose a path to PSI file.
|
||||
By default it monitors system-wide file: /proc/pressure/memory
|
||||
You also can set file to monitor one cgroup slice.
|
||||
For example:
|
||||
psi_path = /sys/fs/cgroup/unified/user.slice/memory.pressure
|
||||
psi_path = /sys/fs/cgroup/unified/system.slice/memory.pressure
|
||||
psi_path = /sys/fs/cgroup/unified/system.slice/foo.service/memory.pressure
|
||||
|
||||
Execute the command
|
||||
find /sys/fs/cgroup | grep -P "memory\.pressure$"
|
||||
to find available memory.pressue files (except /proc/pressure/memory).
|
||||
|
||||
psi_path = /proc/pressure/memory
|
||||
|
||||
Valid psi_metrics are:
|
||||
some_avg10
|
||||
some_avg60
|
||||
some_avg300
|
||||
full_avg10
|
||||
full_avg60
|
||||
full_avg300
|
||||
|
||||
some_avg10 is most sensitive.
|
||||
|
||||
psi_metrics = some_avg10
|
||||
|
||||
sigterm_psi_threshold = 80
|
||||
sigkill_psi_threshold = 90
|
||||
|
||||
psi_post_action_delay = 60
|
||||
|
||||
#####################################################################
|
||||
|
||||
3. The frequency of checking the amount of available memory
|
||||
(and CPU usage)
|
||||
|
||||
Coefficients that affect the intensity of monitoring. Reducing
|
||||
the coefficients can reduce CPU usage and increase the periods
|
||||
between memory checks.
|
||||
|
||||
Why three coefficients instead of one? Because the swap fill rate
|
||||
is usually lower than the RAM fill rate.
|
||||
|
||||
It is possible to set a lower intensity of monitoring for swap
|
||||
without compromising to prevent OOM and thus reduce the CPU load.
|
||||
|
||||
Default values are well for desktop. On servers without rapid
|
||||
fluctuations in memory levels the values can be reduced.
|
||||
|
||||
Valid values are positive floating-point numbers.
|
||||
|
||||
rate_mem = 4000
|
||||
rate_swap = 1500
|
||||
rate_zram = 500
|
||||
|
||||
See also https://github.com/rfjakob/earlyoom/issues/61
|
||||
|
||||
|
||||
Максимальное время сна между проверками памяти.
|
||||
Положительное число.
|
||||
|
||||
max_sleep_time = 3
|
||||
|
||||
Минимальное время сна между проверками памяти.
|
||||
Положительное число, не превышающее max_sleep_time.
|
||||
|
||||
min_sleep_time = 0.1
|
||||
|
||||
#####################################################################
|
||||
|
||||
4. The prevention of killing innocent victims
|
||||
|
||||
Минимальное значение bandess (по умолчанию равно oom_score),
|
||||
которым должен обладать
|
||||
процесс для того, чтобы ему был отправлен сигнал.
|
||||
Позволяет предотвратить убийство невиновных если что-то
|
||||
пойдет не так.
|
||||
|
||||
Valid values are integers from the range [0; 1000].
|
||||
|
||||
min_badness = 20
|
||||
|
||||
Минимальная задержка после отправки соответствующих сигналов
|
||||
для предотвращения риска убийства сразу множества процессов.
|
||||
|
||||
Valid values are non-negative floating-point numbers.
|
||||
|
||||
min_delay_after_sigterm = 0.2
|
||||
min_delay_after_sigkill = 1
|
||||
|
||||
Процессы браузера chromium обычно имеют oom_score_adj
|
||||
200 или 300. Это приводит к тому, что процессы хрома умирают
|
||||
первыми вместо действительно тяжелых процессов.
|
||||
Если параметр decrease_oom_score_adj установлен
|
||||
в значение True, то у процессов, имеющих oom_score_adj выше
|
||||
oom_score_adj_max значение oom_score_adj будет опущено
|
||||
до oom_score_adj_max перед поиском жертвы.
|
||||
|
||||
Enabling the option requires root privileges.
|
||||
Valid values are True and False.
|
||||
Values are case sensitive.
|
||||
|
||||
decrease_oom_score_adj = False
|
||||
|
||||
Valid values are integers from the range [0; 1000].
|
||||
|
||||
oom_score_adj_max = 20
|
||||
|
||||
#####################################################################
|
||||
|
||||
5. Impact on the badness of processes via matching their names,
|
||||
cmdlines or UIDs with regular expressions using re.search().
|
||||
|
||||
See https://en.wikipedia.org/wiki/Regular_expression and
|
||||
https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions
|
||||
|
||||
Enabling this options slows down the search for the victim
|
||||
because the names, cmdlines or UIDs of all processes
|
||||
(except init and kthreads) are compared with the
|
||||
specified regex patterns (in fact slowing down is caused by
|
||||
reading all /proc/*/cmdline and /proc/*/status files).
|
||||
|
||||
Use script `oom-sort` from nohang package to view
|
||||
names, cmdlines and UIDs of processes.
|
||||
|
||||
|
||||
5.1 Matching process names with RE patterns
|
||||
|
||||
Valid values are True and False.
|
||||
|
||||
regex_matching = False
|
||||
|
||||
Syntax:
|
||||
|
||||
@PROCESSNAME_RE badness_adj /// RE_pattern
|
||||
|
||||
New badness value will be += badness_adj
|
||||
|
||||
It is possible to compare multiple patterns
|
||||
with different badness_adj values.
|
||||
|
||||
Example:
|
||||
|
||||
@PROCESSNAME_RE -100 /// ^Xorg$
|
||||
|
||||
@PROCESSNAME_RE -500 /// ^sshd$
|
||||
|
||||
5.2 Matching cmdlines with RE patterns
|
||||
|
||||
A good option that allows fine adjustment.
|
||||
|
||||
re_match_cmdline = False
|
||||
|
||||
@CMDLINE_RE 300 /// -childID|--type=renderer
|
||||
|
||||
@CMDLINE_RE -200 /// ^/usr/lib/virtualbox
|
||||
|
||||
|
||||
5.3 Matching UIDs with RE patterns
|
||||
|
||||
The most slow option
|
||||
|
||||
re_match_uid = False
|
||||
|
||||
@UID_RE -100 /// ^0$
|
||||
|
||||
5.4 Matching CGroup-line with RE patterns
|
||||
|
||||
re_match_cgroup = True
|
||||
|
||||
@CGROUP_RE -50 /// system.slice
|
||||
|
||||
@CGROUP_RE 50 /// foo.service
|
||||
@CGROUP_RE 2000 /// user.slice
|
||||
|
||||
5.5 Matching realpath with RE patterns
|
||||
|
||||
re_match_realpath = False
|
||||
|
||||
@REALPATH_RE 20 /// ^/usr/bin/foo
|
||||
|
||||
Note that you can control badness also via systemd units via OOMScoreAdjust, see
|
||||
https://www.freedesktop.org/software/systemd/man/systemd.exec.html#OOMScoreAdjust=
|
||||
|
||||
#####################################################################
|
||||
|
||||
6. The execution of a specific command instead of sending the
|
||||
SIGTERM signal.
|
||||
|
||||
For processes with a specific name you can specify a command to
|
||||
run instead of sending the SIGTERM signal.
|
||||
|
||||
For example, if the process is running as a daemon, you can run
|
||||
the restart command instead of sending SIGTERM.
|
||||
|
||||
Valid values are True and False.
|
||||
|
||||
execute_the_command = False
|
||||
|
||||
The length of the process name can't exceed 15 characters.
|
||||
The syntax is as follows: lines starting with keyword $ETC are
|
||||
considered as the lines containing names of processes and
|
||||
corresponding commands. After a name of process the triple slash
|
||||
(///) follows. And then follows the command that will be
|
||||
executed if the specified process is selected as a victim. The
|
||||
ampersand (&) at the end of the command will allow nohang to
|
||||
continue runing without waiting for the end of the command
|
||||
execution.
|
||||
|
||||
For example:
|
||||
$ETC mysqld /// systemctl restart mariadb.service &
|
||||
$ETC php-fpm7.0 /// systemctl restart php7.0-fpm.service
|
||||
|
||||
If command will contain $PID pattern, this template ($PID) will
|
||||
be replaced by PID of process which name match with RE pattern.
|
||||
|
||||
Exmple:
|
||||
|
||||
$ETC bash /// kill -KILL $PID
|
||||
|
||||
It is way to send any signal instead of SIGTERM.
|
||||
(run `kill -L` to see list of all signals)
|
||||
|
||||
Also $NAME will be replaced by process name.
|
||||
|
||||
$ETC bash /// kill -9 $PID
|
||||
|
||||
$ETC firefox-esr /// kill -SEGV $PID
|
||||
|
||||
$ETC tail /// kill -9 $PID
|
||||
|
||||
$ETC apache2 /// systemctl restart apache2
|
||||
|
||||
|
||||
#####################################################################
|
||||
|
||||
7. GUI notifications:
|
||||
- OOM prevention results and
|
||||
- low memory warnings
|
||||
|
||||
Включение этой опции требует наличия notify-send в системе.
|
||||
В Debian/Ubuntu это обеспечивается установкой пакета
|
||||
libnotify-bin. В Fedora и Arch Linux - пакет libnotify.
|
||||
Также требуется наличие сервера уведомлений.
|
||||
При запуске nohang от рута уведомления рассылаются всем
|
||||
залогиненным пользователям.
|
||||
See also wiki.archlinux.org/index.php/Desktop_notifications
|
||||
Valid values are True and False.
|
||||
|
||||
gui_notifications = False
|
||||
|
||||
Enable GUI notifications about the low level of available memory.
|
||||
Valid values are True and False.
|
||||
|
||||
gui_low_memory_warnings = False
|
||||
|
||||
Execute the command instead of sending GUI notifications if the value is
|
||||
not empty line. For example:
|
||||
warning_exe = cat /proc/meminfo &
|
||||
|
||||
warning_exe =
|
||||
|
||||
Если значения MemAvailable и SwapFree одновременно будут ниже
|
||||
соотвестствующих значений, то будут отправлены уведомления.
|
||||
|
||||
Can be specified in % (percent) and M (MiB).
|
||||
Valid values are floating-point numbers from the range [0; 100] %.
|
||||
|
||||
mem_min_warnings = 25 %
|
||||
|
||||
swap_min_warnings = 25 %
|
||||
|
||||
Если доля zram в памяти превысит значение zram_max_warnings,
|
||||
то будут отправляться уведомления с минимальным периодом равным
|
||||
min_time_between_warnings.
|
||||
|
||||
zram_max_warnings = 40 %
|
||||
|
||||
Минимальное время между отправками уведомлений в секундах.
|
||||
Valid values are floating-point numbers from the range [1; 300].
|
||||
|
||||
min_time_between_warnings = 15
|
||||
|
||||
Ampersands (&) will be replaced with asterisks (*) in process
|
||||
names and in commands.
|
||||
|
||||
#####################################################################
|
||||
|
||||
8. Verbosity
|
||||
|
||||
Display the configuration when the program starts.
|
||||
Valid values are True and False.
|
||||
|
||||
print_config = False
|
||||
|
||||
Print memory check results.
|
||||
Valid values are True and False.
|
||||
|
||||
print_mem_check_results = False
|
||||
|
||||
Минимальная периодичность печати состояния памяти.
|
||||
0 - печатать все проверки памяти.
|
||||
Неотрицательное число.
|
||||
|
||||
min_mem_report_interval = 60
|
||||
|
||||
Print sleep periods between memory checks.
|
||||
Valid values are True and False.
|
||||
|
||||
print_sleep_periods = False
|
||||
|
||||
Печатать общую статистику по корректирующим действиям с момента
|
||||
запуска nohang после каждого корректирующего действия.
|
||||
|
||||
print_total_stat = True
|
||||
|
||||
Печатать таблицу процессов перед каждым корректирующим действием.
|
||||
|
||||
print_proc_table = False
|
||||
|
||||
print_victim_info = True
|
||||
|
||||
Максимальная глубина показа родословной жертвы.
|
||||
По умолчанию (1) показывается только родитель - PPID.
|
||||
Целое положительное число.
|
||||
|
||||
max_ancestry_depth = 1
|
||||
|
||||
separate_log = False
|
||||
|
||||
psi_debug = False
|
||||
|
||||
#####################################################################
|
||||
|
||||
9. Misc
|
||||
|
||||
Жертва может не реагировать на SIGTERM.
|
||||
max_post_sigterm_victim_lifetime - это время, при превышении
|
||||
которого жертва получит SIGKILL.
|
||||
Неотрицательные числа.
|
||||
|
||||
max_post_sigterm_victim_lifetime = 10
|
||||
|
||||
Execute the command after sending SIGKILL to the victim if the value is
|
||||
not empty line. For example:
|
||||
post_kill_exe = cat /proc/meminfo &
|
||||
|
||||
post_kill_exe =
|
||||
|
||||
forbid_negative_badness = True
|
||||
|
@ -1,194 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# интерактивный oom-trigger
|
||||
|
||||
from memco import *
|
||||
|
||||
from signal import signal, SIGTERM
|
||||
from time import sleep
|
||||
from sys import exit
|
||||
|
||||
|
||||
def signal_handler(signum, frame):
|
||||
print('Got signal {}'.format(signum))
|
||||
# sleep(1)
|
||||
# exit()
|
||||
|
||||
|
||||
signal(SIGTERM, signal_handler)
|
||||
|
||||
|
||||
|
||||
# печать показателей на этапах работы
|
||||
def print_mem():
|
||||
|
||||
mem_tup = mem_check_main()
|
||||
|
||||
mem_available = mem_tup[0]
|
||||
swap_total = mem_tup[1]
|
||||
swap_free = mem_tup[2]
|
||||
|
||||
print(
|
||||
'MemAvailable: ', round(mem_available / 1024 / 1024, 3), 'GiB,', round(mem_available / 1024), 'MiB,', round(mem_available / mem_total * 100, 1), '%'
|
||||
)
|
||||
|
||||
if swap_total != 0:
|
||||
print(
|
||||
'SwapFree: ', round(swap_free / 1024 / 1024, 3), 'GiB,', round(swap_free / 1024), 'MiB,', round(swap_free / swap_total * 100, 1), '%'
|
||||
)
|
||||
print(
|
||||
'Total Free: ', round((mem_available + swap_free) / 1024 / 1024, 3), 'GiB,', round((mem_available + swap_free) / 1024), 'MiB,', round((mem_available + swap_free) / (mem_total + swap_total) * 100, 1), '%'
|
||||
)
|
||||
else:
|
||||
print(
|
||||
'Swap disabled'
|
||||
)
|
||||
|
||||
|
||||
|
||||
# бесконечный жор
|
||||
def inf():
|
||||
|
||||
print(
|
||||
'Вводите целые неотрицательные числа. Чем больше, тем быстрее потребление памяти.\n1000 same обеспечивает потребление на уровне полтора гиг в секунду,\nurandom работает на скорости максимум 170 M/s'
|
||||
)
|
||||
same = input("same: ")
|
||||
urandom = input("urandom: ")
|
||||
|
||||
expanding_list = []
|
||||
|
||||
print(
|
||||
'Процесс неограниченного потребления пошёл... Press Ctrl + C for exit'
|
||||
)
|
||||
|
||||
while True:
|
||||
try:
|
||||
expanding_list.append(os.urandom(int(urandom)))
|
||||
expanding_list.append('#' * int(same))
|
||||
except MemoryError:
|
||||
print('MemoryError, start побайтовая добивалка!')
|
||||
terminal()
|
||||
|
||||
|
||||
|
||||
|
||||
# жор числп гиг
|
||||
def lim():
|
||||
|
||||
expanding_list = []
|
||||
|
||||
n = input('На сколько гигабайт уменьшить доступную память?\n: ')
|
||||
|
||||
print('Погнали тратить ' + n + ' гиг...')
|
||||
|
||||
i = 0
|
||||
|
||||
while True:
|
||||
|
||||
i += 1
|
||||
|
||||
try:
|
||||
expanding_list.append(os.urandom(int(100)))
|
||||
expanding_list.append('#' * int(300))
|
||||
except MemoryError:
|
||||
print('MemoryError!')
|
||||
break
|
||||
if i > 2020202 * int(n):
|
||||
print('DONE')
|
||||
break
|
||||
|
||||
return expanding_list
|
||||
|
||||
|
||||
|
||||
|
||||
# жор до остатка мегабайт
|
||||
def lim2avail():
|
||||
|
||||
expanding_list = []
|
||||
|
||||
n = input(
|
||||
'Сколько мегабайт общей доступной памяти (MemAvailable + SwapFree) оставить?\nВведите целое положительное число: '
|
||||
)
|
||||
|
||||
# проверка на целое положительное
|
||||
if n.isdigit() == True:
|
||||
n = int(n)
|
||||
else:
|
||||
print(
|
||||
'Вы ввели не целое положительное число'
|
||||
)
|
||||
return 0
|
||||
|
||||
if n == 0:
|
||||
print(
|
||||
'Вы ввели не целое положительное число'
|
||||
)
|
||||
return 0
|
||||
|
||||
print(
|
||||
'Погнали уменьшать доступную память до уровня ниже ' + str(n) + ' MiB...'
|
||||
)
|
||||
|
||||
while True:
|
||||
try:
|
||||
expanding_list.append(os.urandom(5000))
|
||||
expanding_list.append('#' * 5000)
|
||||
except MemoryError:
|
||||
print('MemoryError!')
|
||||
break
|
||||
if total_mem_available() <= n:
|
||||
print('DONE')
|
||||
break
|
||||
|
||||
return expanding_list
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print('WARNING: эта прога способна потратить память и повесить систему, будьте осторожны.')
|
||||
print('При ее работе следите за показателями памяти.')
|
||||
|
||||
ex_list = []
|
||||
|
||||
try:
|
||||
while True:
|
||||
|
||||
print()
|
||||
print_mem()
|
||||
print()
|
||||
print('Выберите вариант из списка ниже')
|
||||
print('8 или i или I - запустить бесконечное потребление, предложив выбрать скорость потребления и энтропию')
|
||||
print('7 или l или L - запустить ограниченное потребление заданного числа гигов')
|
||||
print('6 или a или A - жрать память пока количество доступной памяти не опустится ниже заданного')
|
||||
print('0 или с или С - очистить накопления при их наличии')
|
||||
print('q или любой другой символ - выход (можно просто нажать Enter)')
|
||||
|
||||
li = input(': ')
|
||||
|
||||
if li is 'l' or li is 'L' or li is '7':
|
||||
x = lim()
|
||||
ex_list.append(x)
|
||||
elif li is 'i' or li is 'I' or li is '8':
|
||||
inf()
|
||||
elif li is 'c' or li is 'C' or li is '0':
|
||||
ex_list = []
|
||||
x = 0
|
||||
y = 0
|
||||
elif li is '6' or li is 'a' or li is 'A':
|
||||
y = lim2avail()
|
||||
ex_list.append(y)
|
||||
else:
|
||||
exit()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
print_mem()
|
||||
selfterm()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,98 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# proc2log: new processes monitor
|
||||
|
||||
import os
|
||||
import argparse
|
||||
from time import sleep
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
'-p',
|
||||
'--period',
|
||||
help='peroid in seconds between proc checks, default value: 0.1',
|
||||
default=0.1,
|
||||
type=float
|
||||
)
|
||||
args = parser.parse_args()
|
||||
period = args.period
|
||||
|
||||
unknown_name = '<unknown>'
|
||||
|
||||
|
||||
# получение чистого пид сета
|
||||
def foo():
|
||||
proc_list = os.listdir('/proc')
|
||||
proc_set = set()
|
||||
for i in proc_list:
|
||||
if i.isdigit() != True:
|
||||
continue
|
||||
proc_set.add(i)
|
||||
return proc_set
|
||||
|
||||
|
||||
# имя через пид
|
||||
def pid_to_name(pid):
|
||||
try:
|
||||
with open('/proc/' + pid + '/status') as f:
|
||||
for line in f:
|
||||
return line[:-1].split('\t')[1]
|
||||
except FileNotFoundError:
|
||||
return unknown_name
|
||||
|
||||
|
||||
# печать одного пида и имени
|
||||
def print_pid(pid):
|
||||
|
||||
try:
|
||||
with open('/proc/' + pid + '/status') as f:
|
||||
for lineno, line in enumerate(f):
|
||||
name = line[:-1].split('\t')[1]
|
||||
print('+ {}, {}'.format(pid, name))
|
||||
pid_dict[pid] = name
|
||||
if lineno >= 0:
|
||||
break
|
||||
|
||||
except FileNotFoundError:
|
||||
name = pid_dict.pop(pid, unknown_name)
|
||||
print(' - {}, {}'.format(pid, name))
|
||||
|
||||
except ProcessLookupError:
|
||||
name = pid_dict.pop(pid, unknown_name)
|
||||
print(' - {}, {}'.format(pid, name))
|
||||
|
||||
|
||||
# нахождение и печать дельт сетов
|
||||
def delta(old_set):
|
||||
|
||||
new_set = set(os.listdir('/proc'))
|
||||
plus = new_set - old_set
|
||||
minus = old_set - new_set
|
||||
|
||||
if len(plus) > 0:
|
||||
for pid in plus:
|
||||
print_pid(pid)
|
||||
|
||||
if len(minus) > 0:
|
||||
for pid in minus:
|
||||
print_pid(pid)
|
||||
|
||||
return new_set
|
||||
|
||||
|
||||
print('proc2log started with period {} seconds'.format(period))
|
||||
print('+ PID, NAME - PID, NAME')
|
||||
|
||||
# первичное наполнение словаря значениями pid:name для печати имён исчезнувших процессов
|
||||
pid_dict = dict()
|
||||
for pid in foo():
|
||||
pid_dict[pid] = pid_to_name(pid)
|
||||
|
||||
pid_set = set(os.listdir('/proc'))
|
||||
try:
|
||||
while True:
|
||||
pid_set = delta(pid_set)
|
||||
sleep(period)
|
||||
except KeyboardInterrupt:
|
||||
exit()
|
||||
|
@ -1,82 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from ctypes import CDLL
|
||||
from time import sleep
|
||||
from sys import argv
|
||||
|
||||
"""
|
||||
Execute the command
|
||||
find /sys/fs/cgroup -name memory.pressure
|
||||
to find available memory.pressue files (except /proc/pressure/memory).
|
||||
(actual for cgroup2)
|
||||
"""
|
||||
|
||||
if len(argv) > 1:
|
||||
psi_path = argv[1]
|
||||
else:
|
||||
psi_path = '/proc/pressure/memory'
|
||||
|
||||
|
||||
def mlockall():
|
||||
|
||||
MCL_CURRENT = 1
|
||||
MCL_FUTURE = 2
|
||||
MCL_ONFAULT = 4
|
||||
|
||||
libc = CDLL('libc.so.6', use_errno=True)
|
||||
|
||||
result = libc.mlockall(
|
||||
MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT
|
||||
)
|
||||
if result != 0:
|
||||
result = libc.mlockall(
|
||||
MCL_CURRENT | MCL_FUTURE
|
||||
)
|
||||
if result != 0:
|
||||
print('WARNING: cannot lock all memory')
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
mlockall()
|
||||
|
||||
|
||||
def psi_path_to_metrics(psi_path):
|
||||
|
||||
with open(psi_path) as f:
|
||||
psi_list = f.readlines()
|
||||
# print(psi_list)
|
||||
some_list, full_list = psi_list[0].split(' '), psi_list[1].split(' ')
|
||||
#print(some_list, full_list)
|
||||
some_avg10 = some_list[1].split('=')[1]
|
||||
some_avg60 = some_list[2].split('=')[1]
|
||||
some_avg300 = some_list[3].split('=')[1]
|
||||
|
||||
full_avg10 = full_list[1].split('=')[1]
|
||||
full_avg60 = full_list[2].split('=')[1]
|
||||
full_avg300 = full_list[3].split('=')[1]
|
||||
|
||||
return (some_avg10, some_avg60, some_avg300,
|
||||
full_avg10, full_avg60, full_avg300)
|
||||
|
||||
|
||||
print('Path to PSI file: {}\n'.format(psi_path))
|
||||
|
||||
|
||||
print(' avg10 avg60 avg300 avg10 avg60 avg300')
|
||||
|
||||
while True:
|
||||
(some_avg10, some_avg60, some_avg300,
|
||||
full_avg10, full_avg60, full_avg300) = psi_path_to_metrics(psi_path)
|
||||
|
||||
print('some {} {} {} | full {} {} {}'.format(
|
||||
some_avg10.rjust(6),
|
||||
some_avg60.rjust(6),
|
||||
some_avg300.rjust(6),
|
||||
full_avg10.rjust(6),
|
||||
full_avg60.rjust(6),
|
||||
full_avg300.rjust(6)))
|
||||
|
||||
sleep(2)
|
@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from time import sleep, time
|
||||
import os
|
||||
from sys import stdout
|
||||
|
||||
mlockall = True
|
||||
|
||||
if mlockall:
|
||||
from ctypes import CDLL
|
||||
CDLL('libc.so.6').mlockall(3)
|
||||
|
||||
psi_path = '/proc/pressure/memory'
|
||||
|
||||
psi_support = os.path.exists(psi_path)
|
||||
|
||||
def rline1(path):
|
||||
"""read 1st line from path."""
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
return line[:-1]
|
||||
|
||||
def psi_mem_some_avg_total():
|
||||
return float(rline1(psi_path).rpartition('=')[2])
|
||||
|
||||
avg_min_time = 1
|
||||
|
||||
if psi_support:
|
||||
ta0 = time()
|
||||
a0 = psi_mem_some_avg_total()
|
||||
|
||||
while True:
|
||||
|
||||
if psi_support:
|
||||
|
||||
ta1= time()
|
||||
dt = ta1 - ta0
|
||||
|
||||
if dt >= avg_min_time:
|
||||
|
||||
a1 = psi_mem_some_avg_total()
|
||||
avg = (a1 - a0) / (ta1 - ta0) / 10000
|
||||
|
||||
print('avg time:', round(dt, 1))
|
||||
print('PSI mem avg:', round(avg, 2))
|
||||
print(rline1(psi_path), '\n')
|
||||
ta0 = ta1
|
||||
a0 = a1
|
||||
|
||||
stdout.flush()
|
||||
sleep(0.1)
|
133
trash/psi-top
133
trash/psi-top
@ -1,133 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from ctypes import CDLL
|
||||
from time import sleep, time
|
||||
import os
|
||||
|
||||
"""
|
||||
Execute the command
|
||||
find /sys/fs/cgroup -name memory.pressure
|
||||
to find available memory.pressue files (except /proc/pressure/memory).
|
||||
(actual for cgroup2)
|
||||
"""
|
||||
|
||||
psi_path = '/proc/pressure/memory'
|
||||
|
||||
def mlockall():
|
||||
|
||||
MCL_CURRENT = 1
|
||||
MCL_FUTURE = 2
|
||||
MCL_ONFAULT = 4
|
||||
|
||||
libc = CDLL('libc.so.6', use_errno=True)
|
||||
|
||||
result = libc.mlockall(
|
||||
MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT
|
||||
)
|
||||
if result != 0:
|
||||
result = libc.mlockall(
|
||||
MCL_CURRENT | MCL_FUTURE
|
||||
)
|
||||
if result != 0:
|
||||
print('WARNING: cannot lock all memory')
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
mlockall()
|
||||
|
||||
t0 = time()
|
||||
|
||||
def psi_path_to_metrics(psi_path):
|
||||
|
||||
with open(psi_path) as f:
|
||||
psi_list = f.readlines()
|
||||
# print(psi_list)
|
||||
some_list, full_list = psi_list[0].split(' '), psi_list[1].split(' ')
|
||||
#print(some_list, full_list)
|
||||
some_avg10 = some_list[1].split('=')[1]
|
||||
some_avg60 = some_list[2].split('=')[1]
|
||||
some_avg300 = some_list[3].split('=')[1]
|
||||
|
||||
full_avg10 = full_list[1].split('=')[1]
|
||||
full_avg60 = full_list[2].split('=')[1]
|
||||
full_avg300 = full_list[3].split('=')[1]
|
||||
|
||||
return (some_avg10, some_avg60, some_avg300,
|
||||
full_avg10, full_avg60, full_avg300)
|
||||
|
||||
|
||||
|
||||
def cgroup2_root():
|
||||
"""
|
||||
"""
|
||||
with open('/proc/mounts') as f:
|
||||
for line in f:
|
||||
if ' cgroup2 ' in line:
|
||||
# if line.startswith('cgroup2 '):
|
||||
return line[7:].rpartition(' cgroup2 ')[0]
|
||||
|
||||
|
||||
def get_psi_mem_files(cgroup2_path):
|
||||
"""
|
||||
"""
|
||||
|
||||
path_list = []
|
||||
|
||||
for root, dirs, files in os.walk(cgroup2_path):
|
||||
for file in files:
|
||||
path = os.path.join(root, file)
|
||||
if path.endswith('/memory.pressure'): #############
|
||||
path_list.append(path)
|
||||
|
||||
return path_list
|
||||
|
||||
|
||||
def psi_path_to_cgroup2(path):
|
||||
"""
|
||||
"""
|
||||
return path.partition(i)[2][:-16]
|
||||
|
||||
|
||||
i = cgroup2_root()
|
||||
|
||||
print('cgroup2 root dir:', i)
|
||||
if i is not None:
|
||||
y = get_psi_mem_files(i)
|
||||
for path in y:
|
||||
pass # print(psi_path_to_cgroup2(path))
|
||||
|
||||
path_list = get_psi_mem_files(i)
|
||||
|
||||
print(' avg10 avg60 avg300 avg10 avg60 avg300 cgroup2')
|
||||
|
||||
print(' ----- ----- ------ ----- ----- ------ ---------')
|
||||
|
||||
(some_avg10, some_avg60, some_avg300, full_avg10, full_avg60, full_avg300) = psi_path_to_metrics('/proc/pressure/memory')
|
||||
print('some {} {} {} | full {} {} {} {}'.format(
|
||||
some_avg10.rjust(6),
|
||||
some_avg60.rjust(6),
|
||||
some_avg300.rjust(6),
|
||||
full_avg10.rjust(6),
|
||||
full_avg60.rjust(6),
|
||||
full_avg300.rjust(6), '[SYSTEM]'))
|
||||
|
||||
|
||||
for psi_path in path_list:
|
||||
(some_avg10, some_avg60, some_avg300,
|
||||
full_avg10, full_avg60, full_avg300) = psi_path_to_metrics(psi_path)
|
||||
|
||||
print('some {} {} {} | full {} {} {} {}'.format(
|
||||
some_avg10.rjust(6),
|
||||
some_avg60.rjust(6),
|
||||
some_avg300.rjust(6),
|
||||
full_avg10.rjust(6),
|
||||
full_avg60.rjust(6),
|
||||
full_avg300.rjust(6), psi_path_to_cgroup2(psi_path)))
|
||||
|
||||
|
||||
print(time() - t0)
|
||||
|
||||
|
@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from time import sleep, time
|
||||
|
||||
t0 = time()
|
||||
|
||||
hog_list = []
|
||||
|
||||
duration = 60
|
||||
|
||||
sff_max = 0.55
|
||||
sff_min = 0.45
|
||||
|
||||
mb = 1024 * 1024
|
||||
path = '/dev/zero'
|
||||
|
||||
def sff():
|
||||
"""
|
||||
SwapFree fraction
|
||||
"""
|
||||
with open('/proc/meminfo') as f:
|
||||
for i in f:
|
||||
if i.startswith('SwapTotal'):
|
||||
st = i.split(':')[1].strip(' kB\n')
|
||||
if i.startswith('SwapFree'):
|
||||
sf = i.split(':')[1].strip(' kB\n')
|
||||
st = float(st) + 1
|
||||
sf = float(sf)
|
||||
return sf / st
|
||||
|
||||
|
||||
def hog(hog_list):
|
||||
"""
|
||||
"""
|
||||
with open(path, 'rb') as f:
|
||||
raw = f.read(mb)
|
||||
hog_list.append(raw)
|
||||
|
||||
return hog_list
|
||||
|
||||
|
||||
while True:
|
||||
|
||||
while sff() > sff_min:
|
||||
hog_list.reverse()
|
||||
if time() - t0 > duration:
|
||||
exit()
|
||||
hog_list = hog(hog_list)
|
||||
print('MiB:', len(hog_list), 'SwapFree:', sff(), 'time:', time() - t0)
|
||||
|
||||
while sff() < sff_max:
|
||||
hog_list.reverse()
|
||||
if time() - t0 > duration:
|
||||
exit()
|
||||
try:
|
||||
hog_list.pop()
|
||||
except IndexError:
|
||||
break
|
||||
print('MiB:', len(hog_list), 'SwapFree:', sff(), 'time:', time() - t0)
|
||||
|
@ -1,2 +0,0 @@
|
||||
some avg10=56.70 avg60=51.59 avg300=22.92 total=195239452
|
||||
full avg10=28.82 avg60=49.77 avg300=21.83 total=182504463
|
@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import random
|
||||
|
||||
# число элементов в списке, влияет на потребляемую память
|
||||
n = 400 * 1000 * 1000
|
||||
|
||||
# число итераций замены элементов списка
|
||||
c = 10
|
||||
|
||||
print('Наполняем список (n = {}) случайными числами...'.format(n))
|
||||
|
||||
try:
|
||||
# добавляем в пустой список n случайных чисел
|
||||
x = []
|
||||
for _ in range(n):
|
||||
x.append(random.random())
|
||||
|
||||
for i in range(c):
|
||||
print('Читение и запись новых значений, итерация {} из {}'.format(i + 1, c))
|
||||
|
||||
# заменяем элементы списка на новые
|
||||
for i in range(n):
|
||||
x[i] = x[i] * 0.999
|
||||
|
||||
del x
|
||||
|
||||
except KeyboardInterrupt:
|
||||
del x
|
||||
|
25
trash/rawcat
25
trash/rawcat
@ -1,25 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# rawcat 1 999 /path/to/file
|
||||
|
||||
from sys import argv
|
||||
|
||||
print('argv:')
|
||||
print(argv)
|
||||
|
||||
mode = int(argv[1])
|
||||
num = int(argv[2])
|
||||
path = argv[3]
|
||||
|
||||
if mode == 0:
|
||||
with open(path, 'rb') as f:
|
||||
raw = f.read(num)
|
||||
if mode == 1:
|
||||
with open(path, 'rb') as f:
|
||||
raw = f.read(num).decode('utf-8', 'ignore')
|
||||
if mode == 2:
|
||||
with open(path) as f:
|
||||
raw = f.read(num)
|
||||
|
||||
print('raw:')
|
||||
print([raw])
|
17
trash/t01
17
trash/t01
@ -1,17 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from signal import signal, SIGTERM
|
||||
|
||||
def signal_handler(signum, frame):
|
||||
print('Got signal {}'.format(signum))
|
||||
|
||||
signal(SIGTERM, signal_handler)
|
||||
|
||||
rate = 99999
|
||||
|
||||
x = []
|
||||
|
||||
while True:
|
||||
x.append('#' * rate)
|
||||
|
||||
# http://okturing.com/src/6140/body
|
169
trash/thanatolog
169
trash/thanatolog
@ -1,169 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from time import sleep, time
|
||||
from signal import (signal,
|
||||
SIGKILL, SIGTERM, SIGINT, SIGQUIT,
|
||||
SIGCONT, SIGUSR1, SIGUSR2,
|
||||
SIGHUP, SIGABRT, SIGSEGV, SIGBUS)
|
||||
from sys import argv, exit
|
||||
|
||||
|
||||
def mlockall():
|
||||
"""Lock all memory to prevent swapping the process."""
|
||||
|
||||
from ctypes import CDLL
|
||||
|
||||
MCL_CURRENT = 1
|
||||
MCL_FUTURE = 2
|
||||
MCL_ONFAULT = 4
|
||||
|
||||
libc = CDLL('libc.so.6', use_errno=True)
|
||||
|
||||
result = libc.mlockall(
|
||||
MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT
|
||||
)
|
||||
if result != 0:
|
||||
result = libc.mlockall(
|
||||
MCL_CURRENT | MCL_FUTURE
|
||||
)
|
||||
if result != 0:
|
||||
print('WARNING: cannot lock all memory')
|
||||
else:
|
||||
log('All memory locked with MCL_CURRENT | MCL_FUTURE')
|
||||
else:
|
||||
print('All memory locked with MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT')
|
||||
|
||||
|
||||
def check_mem():
|
||||
"""find mem_available"""
|
||||
with open('/proc/meminfo') as f:
|
||||
for n, line in enumerate(f):
|
||||
if n is 2:
|
||||
mem_available = int(line.split(':')[1][:-4])
|
||||
return mem_available
|
||||
|
||||
|
||||
def pid_to_name(pid):
|
||||
"""
|
||||
"""
|
||||
try:
|
||||
with open('/proc/' + pid + '/comm', 'rb') as f:
|
||||
return f.read().decode('utf-8', 'ignore')[:-1]
|
||||
except FileNotFoundError:
|
||||
return ''
|
||||
except ProcessLookupError:
|
||||
return ''
|
||||
|
||||
|
||||
def pid_to_state(pid):
|
||||
|
||||
x = rline1('/proc/' + pid + '/stat')
|
||||
|
||||
if ')' in x:
|
||||
return x.rpartition(')')[2][1]
|
||||
else:
|
||||
return ' '
|
||||
|
||||
|
||||
def pid_to_rss(pid):
|
||||
try:
|
||||
rss = rline1('/proc/{}/statm'.format(pid)).split(' ')[1]
|
||||
except IndexError:
|
||||
rss = '-0'
|
||||
return rss
|
||||
|
||||
|
||||
def pid_to_realpath(pid):
|
||||
try:
|
||||
return os.path.realpath('/proc/' + pid + '/exe')
|
||||
except FileNotFoundError:
|
||||
return ''
|
||||
|
||||
|
||||
def rline1(path):
|
||||
"""read 1st line from path."""
|
||||
try:
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
return line[:-1]
|
||||
except UnicodeDecodeError:
|
||||
with open(path, 'rb') as f:
|
||||
return f.read(999).decode(
|
||||
'utf-8', 'ignore').split('\n')[0] # use partition()!
|
||||
except FileNotFoundError:
|
||||
return 'FileNotFoundError'
|
||||
except ProcessLookupError:
|
||||
return 'ProcessLookupError'
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
if len(argv) != 2:
|
||||
print("""Usage:
|
||||
thanatolog PID""")
|
||||
exit()
|
||||
|
||||
|
||||
mlockall()
|
||||
|
||||
|
||||
pid = argv[1]
|
||||
name = pid_to_name(pid)
|
||||
rss0 = float(pid_to_rss(pid))
|
||||
ma = check_mem()
|
||||
|
||||
|
||||
print('PID:', pid)
|
||||
print('Name:', name)
|
||||
print('RSS at startup: {} (100.0 %)'.format(int(rss0)))
|
||||
print('MemAvail:', ma)
|
||||
|
||||
send_signal = SIGKILL
|
||||
|
||||
# os.kill(int(pid), SIGCONT)
|
||||
|
||||
|
||||
t0 = time()
|
||||
|
||||
|
||||
for i in range(10):
|
||||
rpe = os.path.exists('/proc/{}/exe'.format(pid))
|
||||
rss = pid_to_rss(pid)
|
||||
pe = os.path.exists('/proc/{}'.format(pid))
|
||||
t1 = time()
|
||||
d = t1 - t0
|
||||
state = pid_to_state(pid)
|
||||
ma = check_mem()
|
||||
vv = pid_to_cmdline(pid)
|
||||
print(vv)
|
||||
print('RP: {} | RSS: {} ({} %) | State: {} | time: {} | MemAv'
|
||||
'ail: {}'.format(rpe, rss, round(float(rss) / (
|
||||
rss0 + 0.0001) * 100, 1), state, round(d, 3), ma))
|
||||
|
||||
print('Send SIGKILL')
|
||||
|
||||
os.kill(int(pid), send_signal)
|
||||
|
||||
t0 = time()
|
||||
|
||||
while True:
|
||||
rpe = os.path.exists('/proc/{}/exe'.format(pid))
|
||||
rss = pid_to_rss(pid)
|
||||
pe = os.path.exists('/proc/{}'.format(pid))
|
||||
t1 = time()
|
||||
d = t1 - t0
|
||||
state = pid_to_state(pid)
|
||||
ma = check_mem()
|
||||
|
||||
vv = pid_to_cmdline(pid)
|
||||
print(vv)
|
||||
|
||||
print('RP: {} | RSS: {} ({} %) | State: {} | time: {} | MemAv'
|
||||
'ail: {}'.format(rpe, rss, round(float(rss) / (
|
||||
rss0 + 0.0001) * 100, 1), state, round(d, 3), ma))
|
||||
|
||||
if pe is False:
|
||||
print('Process {} ({}) died in {} sec'.format(pid, name, round(d, 3)))
|
||||
exit()
|
@ -1,177 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from time import sleep, time
|
||||
from signal import (signal,
|
||||
SIGKILL, SIGTERM, SIGINT, SIGQUIT,
|
||||
SIGCONT, SIGUSR1, SIGUSR2,
|
||||
SIGHUP, SIGABRT, SIGSEGV, SIGBUS)
|
||||
from sys import argv, exit
|
||||
|
||||
|
||||
def mlockall():
|
||||
"""Lock all memory to prevent swapping the process."""
|
||||
|
||||
from ctypes import CDLL
|
||||
|
||||
MCL_CURRENT = 1
|
||||
MCL_FUTURE = 2
|
||||
MCL_ONFAULT = 4
|
||||
|
||||
libc = CDLL('libc.so.6', use_errno=True)
|
||||
|
||||
result = libc.mlockall(
|
||||
MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT
|
||||
)
|
||||
|
||||
|
||||
def check_mem():
|
||||
"""find mem_available"""
|
||||
with open('/proc/meminfo') as f:
|
||||
for n, line in enumerate(f):
|
||||
if n is 2:
|
||||
mem_available = int(line.split(':')[1][:-4])
|
||||
return round(mem_available / 1024.0)
|
||||
|
||||
|
||||
def pid_to_name(pid):
|
||||
"""
|
||||
"""
|
||||
try:
|
||||
with open('/proc/' + pid + '/comm', 'rb') as f:
|
||||
return f.read().decode('utf-8', 'ignore')[:-1]
|
||||
except FileNotFoundError:
|
||||
return ''
|
||||
except ProcessLookupError:
|
||||
return ''
|
||||
|
||||
|
||||
def pid_to_state(pid):
|
||||
|
||||
x = rline1('/proc/' + pid + '/stat')
|
||||
|
||||
if ')' in x:
|
||||
return x.rpartition(')')[2][1]
|
||||
else:
|
||||
return ' '
|
||||
|
||||
|
||||
def pid_to_rss(pid, SC_PAGESIZE):
|
||||
try:
|
||||
rss = rline1('/proc/{}/statm'.format(pid)).split(' ')[1]
|
||||
except IndexError:
|
||||
rss = '-0'
|
||||
return round(int(rss) * SC_PAGESIZE / (1024.0 ** 2))
|
||||
|
||||
|
||||
def pid_to_realpath(pid):
|
||||
try:
|
||||
return os.path.realpath('/proc/' + pid + '/exe')
|
||||
except FileNotFoundError:
|
||||
return ''
|
||||
|
||||
|
||||
def rline1(path):
|
||||
"""read 1st line from path."""
|
||||
try:
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
return line[:-1]
|
||||
except UnicodeDecodeError:
|
||||
with open(path, 'rb') as f:
|
||||
return f.read(999).decode(
|
||||
'utf-8', 'ignore').split('\n')[0] # use partition()!
|
||||
except FileNotFoundError:
|
||||
return 'FileNotFoundError'
|
||||
except ProcessLookupError:
|
||||
return 'ProcessLookupError'
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
if len(argv) != 2:
|
||||
print("""Usage:
|
||||
thanatolog PID""")
|
||||
exit()
|
||||
|
||||
|
||||
mlockall()
|
||||
|
||||
SC_PAGESIZE = os.sysconf(os.sysconf_names['SC_PAGESIZE'])
|
||||
pid = argv[1]
|
||||
name = pid_to_name(pid)
|
||||
rss0 = float(pid_to_rss(pid, SC_PAGESIZE))
|
||||
ma = check_mem()
|
||||
|
||||
|
||||
print('PID:', pid)
|
||||
print('Name:', name)
|
||||
print('RSS at startup: {} (100.0 %)'.format(int(rss0)))
|
||||
print('MemAvail:', ma)
|
||||
|
||||
send_signal = SIGKILL
|
||||
|
||||
# os.kill(int(pid), SIGCONT)
|
||||
|
||||
|
||||
t0 = time()
|
||||
|
||||
|
||||
for i in range(10):
|
||||
sleep(0.001)
|
||||
rpe = os.path.exists('/proc/{}/exe'.format(pid))
|
||||
rss = pid_to_rss(pid, SC_PAGESIZE)
|
||||
pe = os.path.exists('/proc/{}'.format(pid))
|
||||
t1 = time()
|
||||
d = t1 - t0
|
||||
state = pid_to_state(pid)
|
||||
ma = check_mem()
|
||||
print('RP: {} | RSS: {} ({} %) | {} | t: {:0<6} | MemAv'
|
||||
'ail: {}'.format(rpe, rss, round(float(rss) / (
|
||||
rss0 + 0.0001) * 100, 1), state, str(round(d, 4)), ma))
|
||||
|
||||
|
||||
print()
|
||||
|
||||
print('Send SIGKILL')
|
||||
|
||||
os.kill(int(pid), send_signal)
|
||||
|
||||
t0 = time()
|
||||
|
||||
ma0 = ma
|
||||
|
||||
|
||||
while True:
|
||||
sleep(0.001)
|
||||
rpe = os.path.exists('/proc/{}/exe'.format(pid))
|
||||
rss = pid_to_rss(pid, SC_PAGESIZE)
|
||||
pe = os.path.exists('/proc/{}'.format(pid))
|
||||
t1 = time()
|
||||
d = t1 - t0
|
||||
state = pid_to_state(pid)
|
||||
ma = check_mem()
|
||||
|
||||
print('RP: {} | RSS: {} ({} %) | State: {} | time: {} | MemAvail: {} | dMA {}'.format(
|
||||
rpe, rss, round(float(rss) / (rss0 + 0.0001) * 100, 1), state, round(d, 3), ma, ma0 - ma))
|
||||
|
||||
if pe is False:
|
||||
break
|
||||
|
||||
print('Process {} ({}) died in {} sec'.format(pid, name, round(d, 3)))
|
||||
|
||||
|
||||
print()
|
||||
for i in range(10):
|
||||
sleep(0.001)
|
||||
rpe = os.path.exists('/proc/{}/exe'.format(pid))
|
||||
rss = pid_to_rss(pid, SC_PAGESIZE)
|
||||
pe = os.path.exists('/proc/{}'.format(pid))
|
||||
t1 = time()
|
||||
d = t1 - t0
|
||||
state = pid_to_state(pid)
|
||||
ma = check_mem()
|
||||
|
||||
print('RP: {} | RSS: {} ({} %) | State: {} | time: {} | MemAvail: {} | dMA {}'.format(
|
||||
rpe, rss, round(float(rss) / (rss0 + 0.0001) * 100, 1), state, round(d, 3), ma, ma0 - ma))
|
124
trash/x01
124
trash/x01
@ -1,124 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
from os import getpid
|
||||
|
||||
# find mem_total
|
||||
# find positions of SwapFree and SwapTotal in /proc/meminfo
|
||||
|
||||
with open('/proc/meminfo') as f:
|
||||
mem_list = f.readlines()
|
||||
|
||||
mem_list_names = []
|
||||
for s in mem_list:
|
||||
mem_list_names.append(s.split(':')[0])
|
||||
|
||||
if mem_list_names[2] != 'MemAvailable':
|
||||
errprint('WARNING: Your Linux kernel is too old, Linux 3.14+ requied')
|
||||
# exit(1)
|
||||
|
||||
swap_total_index = mem_list_names.index('SwapTotal')
|
||||
swap_free_index = swap_total_index + 1
|
||||
|
||||
mem_total = int(mem_list[0].split(':')[1][:-4])
|
||||
|
||||
# Get names from /proc/*/status to be able to get VmRSS and VmSwap values
|
||||
|
||||
with open('/proc/self/status') as file:
|
||||
status_list = file.readlines()
|
||||
|
||||
status_names = []
|
||||
for s in status_list:
|
||||
status_names.append(s.split(':')[0])
|
||||
|
||||
ppid_index = status_names.index('PPid')
|
||||
vm_size_index = status_names.index('VmSize')
|
||||
vm_rss_index = status_names.index('VmRSS')
|
||||
vm_swap_index = status_names.index('VmSwap')
|
||||
uid_index = status_names.index('Uid')
|
||||
state_index = status_names.index('State')
|
||||
|
||||
|
||||
try:
|
||||
anon_index = status_names.index('RssAnon')
|
||||
file_index = status_names.index('RssFile')
|
||||
shmem_index = status_names.index('RssShmem')
|
||||
detailed_rss = True
|
||||
# print(detailed_rss, 'detailed_rss')
|
||||
except ValueError:
|
||||
detailed_rss = False
|
||||
# print('It is not Linux 4.5+')
|
||||
|
||||
|
||||
|
||||
self_pid = str(getpid())
|
||||
|
||||
|
||||
def self_rss():
|
||||
r = pid_to_status(self_pid)[5]
|
||||
print(r)
|
||||
|
||||
|
||||
|
||||
def pid_to_status(pid):
|
||||
"""
|
||||
"""
|
||||
|
||||
try:
|
||||
|
||||
with open('/proc/' + pid + '/status') as f:
|
||||
|
||||
for n, line in enumerate(f):
|
||||
|
||||
if n is 0:
|
||||
name = line.split('\t')[1][:-1]
|
||||
|
||||
if n is state_index:
|
||||
state = line.split('\t')[1][0]
|
||||
continue
|
||||
|
||||
if n is ppid_index:
|
||||
ppid = line.split('\t')[1][:-1]
|
||||
continue
|
||||
|
||||
if n is uid_index:
|
||||
uid = line.split('\t')[2]
|
||||
continue
|
||||
|
||||
if n is vm_size_index:
|
||||
vm_size = int(line.split('\t')[1][:-4])
|
||||
continue
|
||||
|
||||
if n is vm_rss_index:
|
||||
vm_rss = int(line.split('\t')[1][:-4])
|
||||
continue
|
||||
|
||||
if n is vm_swap_index:
|
||||
vm_swap = int(line.split('\t')[1][:-4])
|
||||
break
|
||||
|
||||
return name, state, ppid, uid, vm_size, vm_rss, vm_swap
|
||||
|
||||
except UnicodeDecodeError:
|
||||
return pid_to_status_unicode(pid)
|
||||
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
|
||||
except ProcessLookupError:
|
||||
return None
|
||||
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
self_rss()
|
||||
|
||||
|
||||
import logging
|
||||
import subprocess
|
||||
import argparse
|
||||
|
||||
|
||||
self_rss()
|
||||
|
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Deactivate swap
|
||||
swapoff /dev/zram0
|
||||
|
||||
# Reset zram
|
||||
echo 1 > /sys/block/zram0/reset
|
||||
|
||||
# Remove zram module
|
||||
modprobe -r zram
|
@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# загружаем в ядро модуль zram
|
||||
modprobe -v zram num_devices=4
|
||||
|
||||
# задаем число потоков сжатия, равное числу ядер процессора
|
||||
CPUS="`nproc`"
|
||||
echo "$CPUS" > /sys/block/zram0/max_comp_streams
|
||||
|
||||
# выбираем алгоритм сжатия, lz4 наиболее быстр, lzo сильнее сжимает
|
||||
ALG=lzo
|
||||
echo "$ALG" > /sys/block/zram0/comp_algorithm
|
||||
|
||||
# задаем размер zram (FRACTION - размер устройства zram0 в процентах от MemTotal)
|
||||
FRACTION=100
|
||||
MEMORY=`perl -ne'/^MemTotal:\s+(\d+)/ && print $1*1024;' < /proc/meminfo`
|
||||
SIZE=$(( MEMORY * FRACTION / 100 ))
|
||||
|
||||
echo $SIZE > /sys/block/zram0/disksize
|
||||
#echo 10G > /sys/block/zram0/disksize # можно задать размер zram в гигабайтах, вместо процентов от MemTotal
|
||||
|
||||
# форматируем устройство zram0 как swap
|
||||
mkswap -L zram0 /dev/zram0
|
||||
|
||||
# включаем подкачку
|
||||
swapon -d -p 10 /dev/zram0
|
||||
|
Loading…
Reference in New Issue
Block a user