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として**/usr/share/pixmap**配下に置く。
(/usr/share/pixmap以外に配置する場合にはpathを指定しなければならない)。
--iconで指定する際には拡張子を省く。
$ notify-send -u critical --icon=shikaruhaha "母の声" "<b>J( 'д')し たかし!散らかしっぱなしにしてるんじゃないよ!</b>"
上を実行するとこうなる。
コード
#!/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/以下に配置する。ログイン後、自動的に起動するようになる。
[Desktop Entry]
Name=MemoryMother
Type=Application
Exec=/usr/libexec/memwarn.py
OnlyShowIn=GNOME;
NoDisplay=true
これでおしまい
まとめ
- メモリ増設しろとか言わないで
- いくら何でも依存心が強すぎでは
- 実は"たかし"という名前ではない