Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

プロセス処理中のメモリ使用量測 定に関して

170 views
Skip to first unread message

Takahiko KAWASHIMA

unread,
Apr 14, 2001, 9:59:35 AM4/14/01
to

河島と申します。

ご存知のからいられましたら、教えてください。

ps -eylなんかで以下のプログラムの動作中のメモリ使用量をみてやると、
delete のところでメモリが解放されているつもりなのですが、結果は解放
されているようにみえません。なんでなんでしょうか?
ちなみに、オブジェクトはSunコンパイラのCCでコンパイルしています。
OSはSolaris2.6(Sparc)です。
また、プロセス動作中のメモリ獲得解放の推移を見るよい方法があれば、
あわせて教えてもらえませんか?

#include <unistd.h>
int main()
{
sleep(10);
char* a = new char[200000000];
sleep(10);
delete[] a;
sleep(10);
return 0;
}


---
----------------------------------------------
Takahiko KAWASHIMA
tkaw...@alles.or.jp
----------------------------------------------

Shinji KONO

unread,
Apr 14, 2001, 10:45:12 AM4/14/01
to
河野 真治@琉球大情報工学です。

In article <9b9ld3$52v$1...@news.alles.or.jp> ,
Takahiko KAWASHIMA <tkaw...@alles.or.jp> writes

>ps -eylなんかで以下のプログラムの動作中のメモリ使用量をみてやると、
>delete のところでメモリが解放されているつもりなのですが、結果は解放
>されているようにみえません。なんでなんでしょうか?

Unix では、またすぐ使う可能性の方が大きいので、ユーザ空間を
縮小するようなことはしてないからです。

>また、プロセス動作中のメモリ獲得解放の推移を見るよい方法があれば、
>あわせて教えてもらえませんか?

自分自身でって言う意味ですよね。

getrusage - get information about resource utilization

だと思います。あるいは、

sbrk(0)

の動きを見ても良いはずです。また、これを使って、実際にユーザ空間を
縮小することも出来ます。

delete で、sbrk 的にメモリ空間を小さくするには、自分で、allocator
を書けば良いはずです。たぶん、GC と併用することになるんでしょうね。
かなり高度な問題になります。

でも、気にせずにほっぽって置くのも、Unix 的だし、特に問題はない
はずです。

---
Shinji KONO @ Information Engineering, University of the Ryukyus,
PRESTO, Japan Science and Technology Corporation
河野真治 @ 琉球大学工学部情報工学科,
科学技術振興事業団さきがけ研究21(機能と構成)

KATAYAMA Yoshio

unread,
Apr 15, 2001, 1:38:29 AM4/15/01
to
In article <22031.9...@rananim.ie.u-ryukyu.ac.jp>,
ko...@ie.u-ryukyu.ac.jp (Shinji KONO) writes:

> sbrk(0)
>の動きを見ても良いはずです。また、これを使って、実際にユーザ空間を
>縮小することも出来ます。

>delete で、sbrk 的にメモリ空間を小さくするには、自分で、allocator
>を書けば良いはずです。たぶん、GC と併用することになるんでしょうね。
>かなり高度な問題になります。

sbrk() でやるには、(sbrk() を直接/間接的に使う)すべてのメモリ
管理を書き換えなければならず、現実的には不可能です。

どうしてもやりたい(e.g. ライフタイムが短くサイズが大きいデータ)
のでしたら、mmap() を使うのが現実的でしょう。
--
片山@PFU

HASHIMOTO, Tsuyoshi

unread,
Apr 16, 2001, 5:21:18 AM4/16/01
to
In article <9b9ld3$52v$1...@news.alles.or.jp> Takahiko KAWASHIMA <tkaw...@alles.or.jp> writes:

>ps -eylなんかで以下のプログラムの動作中のメモリ使用量をみてやると、
>delete のところでメモリが解放されているつもりなのですが、結果は解放
>されているようにみえません。なんでなんでしょうか?

既に河野さんの記事 <22031.9...@rananim.ie.u-ryukyu.ac.jp> で説明
されていますが,後の話との関連で,より細かく言い直しておきますと ...

heap 領域を確保する関数 malloc が sbrk(2) (or brk(2)) で実装されている
場合, malloc() を契機に (sbrk(2) で)獲得した仮想空間を free() しても
OS には返却せず「後で mallocを呼んだときに割り当てるためにとっておく」
動作をしているからです.(Solaris の malloc(3c),malloc(3x), あるいは
bsdmalloc(3x) ではそうであり,他の OS 上の compiler/linker 環境でも,
そうなっている事の方が普通である(default 設定として多い)ようです.)

>ちなみに、オブジェクトはSunコンパイラのCCでコンパイルしています。
>OSはSolaris2.6(Sparc)です。

以下,この環境での話です.(私は SUN Workshop 5.0 の C++ で試しました.)

compile の時に,特に library を指定しなければ,標準の malloc を link
するので上のようになります.mapmalloc(3x) の malloc/free を link する
指定をすれば,new では mmap で獲得され,delete 時に munmap により解放
されます.(new/delete が malloc/free で実装されているので,malloc/free
として違う動作をするものを link すれば,動きが変ります.)

load module を修正せず,とりあえず試したい場合は,下記で可能です.

truss -f -tmmap,munmap env LD_PRELOAD=libmapmalloc.so.1 ./prog
sotruss -f -T/usr/lib/libmapmalloc.so.1 env LD_PRELOAD=libmapmalloc.so.1 ./prog

load module を link しなおせば,env LD_PRELOAD=libmapmalloc.so.1 配下
で動かすことなく,mapmalloc を使うようにできます.i.e.

CC -o prog prog.c -lmapmalloc
truss -tmmap,munmap ./prog
sotruss -F/usr/lib/libCrun.so.1 -T/usr/lib/libmapmalloc.so.1 ./prog

# sotruss は default では,他の library 関数から間接呼び出しの場合には,
# 表示しないため,間接呼び出し元を -F に指定する必要がありました.なお,
# ldd(1) で link している shared library を見て,名前から libCrun.so.1
# が C++ の runtime system である事は推定可能でした.

>また、プロセス動作中のメモリ獲得解放の推移を見るよい方法があれば、
>あわせて教えてもらえませんか?

(既に上で一部触れましたが)「process への仮想空間割り当て契機」を見る
には,下記のような手段があります.

(1) 既に上で見た truss による方法 (同様に sotruss による方法もあります)

# なお,Solaris 7 以降なら,sotruss より truss の -u option の方が便利
# かも知れません.

- brk/sbrk と mmap/munmap の領域だけ見る場合,

truss -tbrk,mmap,munmap program [args]
# 起動済みの process を途中から調べる場合,下記のように指定(以下同様)
# truss -tbrk,mmap,munmap -p pid

- (stack も含め)実メモリ割り当て契機である page fault を見る場合

truss -tbrk,mmap,munmap -mfltpage program [args]

#「実メモリを奪われる timing」 を同様に trace する事は難しいと思います.
# OS の "page stealing" の契機次第なので ... しかし,この動作は通常の
# process が timing を気にするものではなく,特に問題はないと思います.

- brk/sbrk と mmap/munmap の他,SysV share memory 領域も見るなら,

truss -tbrk,mmap,munmap,shmat,shmdt program [args]

(2) dmalloc (http://dmalloc.com/) のログファイルによる方法

- 詳しくは上記 URL を参照して下さい.
- 同様な free/市販の library は他にもあると思います.
- SysV shared memory の獲得/解放には対応していないと思います.
(しかし,SysV shared memory を使わないなら,問題ありません).

(3) 各種の debugger あるいは proc(4) を使う(自作含む)ツールにより
メモリ割り当て関数呼び出しを trace する方法

- 割り当てをトレースするだけなら,(1),(2) と本質的には同じです.
- 適当な箇所で停めて /usr/proc/bin/ にある pmap(1) (-rxlF などの
options あり) を使うと,どういう種類のメモリ領域を割り当て済みか
表示できる.
- proc(4) の map を読み出せば,pmap(1) で表示されるような情報を
(自作の)program から参照できる.(なお,自 process の情報なら
/proc/self 一般に pid が分かれば /proc/<pid> の下を見ればよい.)

なお,「メモリ割り当て/アクセス関連の障害箇所を探す」という意味あい
がある場合,

(a) watchmalloc(3x) を使う,
(b) SUN の dbx を install 済みなら,その「run time check 機能」を使う,
(c) その他の(市販)ツール(rational software の purify など)を使う

など「access 状況まで含めたトレース」が有効かも知れません.
--
橋本 剛 (HASHIMOTO, Tsuyoshi)

0 new messages