| Tripletail documentation | Contained in the Tripletail distribution. |
Tripletail::MemorySentinel - メモリ使用状況の監視
my $msenti = $TL->getMemorySentinel; $msenti->setPermissibleSize(db_cache => 10 * 1024); my $usage = $msenti->getMemorySize;
FCGI モードの際に、メモリリークが発生しているかどうかを調べて、 リークを検出した場合にプロセスを再起動する。このモジュールは FCGI モードで自動的に使用され、FCGI モードでない時には使用されない。
このモジュールは、最初に "Main関数" in Tripletail を抜けた時の仮想メモリサイズを 保存する。そして次回以降に "Main関数" in Tripletail を抜けた際、最初の時点に対する仮想 メモリサイズの増加が設定値を越えていれば、メモリリークが発生したと判断する。
$TL->getMemorySentinelmy $msenti = $TL->getMemorySentinel;
Tripletail::MemorySentinel オブジェクトを取得。
getMemorySizemy $usage = $TL->getMemorySize;
現在のメモリ使用量を取得する。
setPermissibleSize$msenti->setPermissibleSize(db_cache => 10 * 1024);
許容メモリ使用量を設定する。 第一引数にはその設定に対するキーを渡し、第二引数にはサイズを KiB 単位で渡す。
デフォルトでは次の設定がされている。
$msenti->setPermissibleSize(_HEAP => 10 * 1024);
getTotalPermissibleSizemy $total = $msenti->getTotalPermissibleSize;
全てのキーに対する許容メモリ使用量の合計値を返す。
現在の所、このモジュールは次の OS からのみメモリ使用量を取得する事が出来る。 これ以外の OS ではメモリリークの検出は行なわれない。
Copyright 2006 YMIRLINK Inc.
This framework is free software; you can redistribute it and/or modify it under the same terms as Perl itself
このフレームワークはフリーソフトウェアです。あなたは Perl と同じライセンスの 元で再配布及び変更を行うことが出来ます。
Address bug reports and comments to: tl@tripletail.jp
HP : http://tripletail.jp/
| Tripletail documentation | Contained in the Tripletail distribution. |
# ----------------------------------------------------------------------------- # Tripletail::MemorySentinel - ã¡ã¢ãªä½¿ç¨ç¶æ³ã®ç£è¦ # ----------------------------------------------------------------------------- package Tripletail::MemorySentinel; use strict; use warnings; use Tripletail; sub _HOOK_PRIORITY() { 2_000_000 } # é åºã¯åããªã our $_INSTANCE; 1; sub _getInstance { my $class = shift; if(!$_INSTANCE) { $_INSTANCE = $class->_new(@_); } $_INSTANCE; } sub __install { my $this = shift; $TL->setHook('postRequest', _HOOK_PRIORITY, sub { $this->__postRequest }); } sub _new { my $class = shift; my $this = bless {} => $class; $this->{getmemfunc} = undef; # ã¡ã¢ãªä½¿ç¨éãåå¾ããçºã®é¢æ°ã'NONE'ãªãåå¨ããªãã $this->{getmemfh} = undef; $this->{initial} = undef; # æåã®postRequestã®æç¹ã§ã®ã¡ã¢ãªä½¿ç¨é $this->{permissible} = {}; # {key => size} ç¨éå¥ã®ã¡ã¢ãªä½¿ç¨è¨±å®¹é $this->setPermissibleSize(_HEAP => 10 * 1024); # 10 MiB $this; } sub getMemorySize { my $this = shift; if(!defined($this->{getmemfunc})) { my $uname = eval { $^O eq 'MSWin32' and die 'MSWin32 is not supported'; `uname -sr`; }; if($@) { $TL->log(__PACKAGE__, "Failed to exec `uname -sr`. [$@]"); $uname = $^O; } else { $uname =~ s/^\s*|\s*$//g; if ($TL->INI->get(TL => memorylog => 'leak') eq 'full') { $TL->log(__PACKAGE__, "Uname is [$uname]"); } } if($uname =~ m/^Linux 2\./) { $this->{getmemfunc} = \&__getMemLinux2; } else { $TL->log(__PACKAGE__, "We can't get memory usage on [$uname] currently..."); $this->{getmemfunc} = 'NONE'; } } if(ref($this->{getmemfunc})) { $this->{getmemfunc}($this); } else { 0; } } sub setPermissibleSize { my $this = shift; my $key = shift; my $size = shift; $this->{permissible}{$key} = $size; $this; } sub getTotalPermissibleSize { my $this = shift; my $total = 0; foreach(values %{$this->{permissible}}) { $total += $_; } $total; } sub __getMemLinux2 { my $this = shift; local $/ = undef; my $fh = $this->{getmemfh}; if(!defined($fh)) { unless(open $fh, '<', "/proc/$$/status") { $TL->log(__PACKAGE__, "Failed to read /proc/$$/status"); return 0; } $this->{getmemfh} = $fh; } else { seek $fh, 0, 0; } my $stat = <$fh>; if($stat =~ m/^VmSize:\s*(\d+)/m) { return $1; } else { $TL->log(__PACKAGE__, "Failed to get VmSize from /proc/$$/status"); } 0; } sub __postRequest { my $this = shift; if(!defined($this->{initial})) { $this->{initial} = $this->getMemorySize; } my $initial = $this->{initial}; my $current = $this->getMemorySize; my $allowed = $this->getTotalPermissibleSize; my $filecache = $TL->_filecacheMemorySize; my $remaining = $initial + $filecache + $allowed - $current; # [=initial=========][=filecache==][=allowed=======] # [=current==============================][=remain=] my $mem_usage = sprintf( "Memory Usage: \n". " [current: %s KiB]\n". " [initial: %s KiB]\n". " [filecache: %s KiB]\n". " [allowed: %s KiB]\n". " [remaining: %s KiB]", $current, $initial, $filecache, $allowed, $remaining); my $switch = $TL->INI->get(TL => 'memorylog', 'leak'); if (($switch eq 'leak' and $remaining < 0) or $switch eq 'full') { $TL->log( __PACKAGE__, $mem_usage); } if ($switch ne 'leak' and $switch ne 'full') { $TL->log( __PACKAGE__, sprintf('unknown [TL]memoryleak parameter: "%s"', $switch)); } if ($remaining < 0) { $TL->log("Tripletail::MemorySentinel detected a possible memory leak.\n\n$mem_usage"); $TL->_fcgi_restart(1); } } __END__