LoginSignup
130
43

More than 3 years have passed since last update.

メモリがカツカツな時お母さんに片付けろと怒られたい

Last updated at Posted at 2020-04-16

2020年になってもメモリの心配をしながら生きている

8GBのノートPCで、VSCode + 何らかのビルド + Chromeでタブ20個とか開いているとあっという間にメモリが足りなくなる。OSごとストールとか大変に厳しいユーザ体験である。

思えば幼少時から物を出しっぱなしにしては母に叱責を受ける事が多々あった。
単なるメモリ容量の不足というより、癒やし難い子供の頃からの性分がそもそもの原因かも知れない。

もはや自分の振る舞いを矯正するよりもその都度母に怒られたほうが良さそうな気がして来た。
というわけで、メモリがカツカツな時デスクトップに不要なソフトを閉じるよう警告を出してくれる母の如きアプリを作成する。

環境・使用言語

  • Ubuntu18.04 + gnome3環境
  • python3
    • ※コマンドをパイプで繋いでもできる内容だが、ubuntuのシステムでもう既にpython3が動いているからpython3で良いかという消極的理由

利用可能なメモリ容量を取得する

Linuxで利用可能なメモリ容量を取得する時、一般的にはfreeコマンドを使う。

$ free
              total        used        free      shared  buff/cache   available
Mem:        8124668     4831144      267628      201468     3025896     2774924
Swap:       2097148         512     2096636

このうち利用可能な実メモリ容量はMem行のavailableの列である。
ざっくり言うとこの値は [空き容量 + 使用済みのキャッシュ等すぐに解放可能な容量] で計算されている(らしい)。

このfreeコマンドの内容は、/proc/meminfo疑似ファイルの内容を整形したものである。
pythonから利用するにはファイルの方が扱いやすいので/proc/meminfoから情報を拾う

~$ cat /proc/meminfo 
MemTotal:        8124668 kB
MemFree:          328384 kB
MemAvailable:    2640012 kB
Buffers:          740992 kB
・・・()

インタラクティブシェル上でファイルをOpenしてみる。
split()関数によって改行・空白で区切り、何番目にAvailableが来ているかを確かめる。

>>> f = open('/proc/meminfo')
>>> f.read().split()
['MemTotal:', '8124668', 'kB', 'MemFree:', '318860', 'kB', 'MemAvailable:', '2631456', 'kB', ...]
>>> f.seek(0)
0
>>> f.read().split()[7]
'2625528'

インデックスが7の要素が0.5GB(500,000kB)を切った時に通知を出せば良いわけである。
(0.5GBの根拠はなんとなくである)

ちなみに、上の例からも分かるようにOpenした後もReadする度に内容が更新される。

デスクトップに通知を飛ばす

notify-sendコマンドを使う。書式は以下の通り。

$ notify-send -u critical --icon=アイコン名 "タイトル" "メッセージ"
  • -u には通知の種別を指定する。内容的に怒られなのでcriticalで良いと思う。
  • --iconでアイコンを指定できる。カスタムアイコンも指定できる。後述。
  • メッセージには簡単なマークアップを使用できる。

アイコンを作る

いらすとやさんから母親アイコンをお借りして使用する(実写の母親も検討したが迫力があり精神の憔悴を感じた)。

shikaruhaha.png

出来上がったアイコンをshikaruhaha.pngとして/usr/share/pixmap配下に置く。
(/usr/share/pixmap以外に配置する場合にはpathを指定しなければならない)。
--iconで指定する際には拡張子を省く。

$ notify-send -u critical --icon=shikaruhaha "母の声" "<b>J( 'д')し  たかし!散らかしっぱなしにしてるんじゃないよ!</b>"

上を実行するとこうなる。

notify.png

コード

memwarn.py
#!/usr/bin/python3
import time
import subprocess

with open("/proc/meminfo") as f:
    while(True):
        f.seek(0)
        arr = f.read().split()
        available = int(arr[7])
        if available < 500000:
            subprocess.call(['notify-send', "-u", "critical", "--icon=shikaruhaha", "母の声", "<b>J( 'д')し  たかし!散らかしっぱなしにしてるんじゃないよ!</b>"])
        time.sleep(2)

  • 2秒間隔でループ
  • f.seek(0)で読み込み位置を強制的に戻す(一度読み込むと読み込み位置が末尾になるため)
  • シェルの実行にはsubprocess.callを使用する。シェルのコマンドを空白で区切った文字列のリストを渡す。
  • memwarn.py というファイル名で実行権限を付与し、/usr/libexec/以下に配置する。

デプロイ

X環境でのログイン後にスタートさせる。
以下のファイルを/etc/xdg/autostart/以下に配置する。ログイン後、自動的に起動するようになる。

/etc/xdg/autostart/memwarn.desktop
[Desktop Entry]
Name=MemoryMother
Type=Application
Exec=/usr/libexec/memwarn.py
OnlyShowIn=GNOME;
NoDisplay=true

これでおしまい

まとめ

  • メモリ増設しろとか言わないで
  • いくら何でも依存心が強すぎでは
  • 実は"たかし"という名前ではない

参考

130
43
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
130
43