limitusus’s diary

主に技術のことを書きます

Linuxのプロセス毎メモリ使用量を調べてみた

大学の課題で「いろいろな条件下で各プロセスのメモリ使用量を調べよ」というのが出ました。メモリ使用量は/proc/PID/smapsに書かれているということを知ったので、それを使ってみることにしました。
もうレポート提出してからだいぶ日が経過したので公開してしまおうと思います。
カーネルによってはsmapsが存在しないとか。そういう場合には使えません。

今回も例によってPerlで書くことに。どうやらCPANに(ryということでLinux::Smapsを使っています。
プログラムは追記に置いておきます。

ロジックを軽く書いておきます。

  • pid_list()が/proc中にある適切なPID(数字の連続)のリストへのリファレンスを返します。
  • 各PIDについてLinux::Smapsのオブジェクトを生成し、Linux::Smaps::sizeメソッドがメモリ使用量を返します。最後にまとめて出力します。
  • 残念なことにLinux::Smapsではプロセス名が分からないので、get_proc_name(PID)によって/proc/PID/smapsを開いて先頭行からプロセス名を引っ張り出しています。

コメントにも書いてありますがroot権限でしか動きませんのでご注意ください。
改造や再配布はご自由に。

出力は標準出力。フォーマットは
PID メモリ消費量 プロセス名[改行]
となっています。出力の1行目を参照してください。

私のレポートではこの結果をRで処理してPie Chartにしました。

process_mem.pl

#!/usr/bin/perl

# Created by Limit <limit.usus@gmail.com>
# http://d.hatena.ne.jp/limitusus/

# *** RUN WITH ROOT PERMISSION ***

use strict;
use warnings;
use Linux::Smaps;
# Setting
my $prefix = q|/proc|;

my $pids = pid_list();
print qq|# PID SIZE PROCESSNAME\n|;
for my $pid (@$pids) {
  #print $pid, $/;
  my $smaps = new Linux::Smaps($pid) or die "Can't open smaps";
  $smaps->update;
  next if $smaps->size == 0;
  print qq|$pid |, $smaps->size ," ", get_proc_name($pid), $/;
}

sub pid_list {
  opendir PROC, $prefix or die "Can't open dir!";
  my @files = readdir PROC;
  my @pids = ();
  for my $pid (@files) {
	next if ($pid !~ (/\d+/));
	push @pids, $pid;
  }
  closedir PROC;
  return \@pids;
}

sub get_proc_name {
  my $pid = shift;
  open SMAPS, "/proc/$pid/smaps" or die "Can't open smaps";
  my $line = <SMAPS>;
  my @array = split /\s+/, $line;
  close SMAPS;
  return $array[$#array];
}