[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[plamo:21935] Re: 物理メモリサイズを取得する方法を教えて下さい
-
From:Shun-ichi TAHARA (田原 俊一)
-
Date:Thu, 5 Feb 2004 15:24:11 +0900 (JST)
- Subject: [plamo:21935] Re: 物理メモリサイズを取得する方法を教えて下さい
- From: Shun-ichi TAHARA (田原 俊一) <jado@xxxxxxxxxxxxxxx>
- Date: Thu, 05 Feb 2004 15:24:08 +0900 (JST)
# 仕事では、4GB のマシンで malloc() failed を出したりします :-)。
From: Iwasa Dai <iwasad@alpha.co.jp>
Message-Id: <20040205.120622.41626489.uaitne@dream.com>
> > 下記の様なプログラムで,PCに実装されているRAMの内,
> > ユーザプログラムから使えるサイズを取得したいのですが,
> > どうも,RAM領域を越えてしまいます。
> > 64MBを持つPCで,実効しますと。
> > Linuxでは,SWAP分も加わるような傾向です。(約200MB)
少なくともユーザプロセスに対しては、1セグメント 4GB の仮想メモリ空間が
当てがわれます (i386 Linux の場合)。さらに、この 4GB の空間を 3つに分
割して管理しています。頭1GB分の空間がカーネルに割り当てられて、以下
2GB がスタック + mmap、最後の 1GB が heap + text に割り当てられます
(CONFIG_HIGHMEM=n の場合)。
CONFIG_HIGHMEM=n は「実メモリ 1GB 以下の人用」となっているのは、このメ
モリマップ (text + heap が 1GB しか取ってない) に起因しています。
有限の実メモリは、各プロセスごとに持っているセグメント空間のどこかに振
られていることになりますが、実際にこの空間のうちのどこが実メモリにマッ
プされて、どこがスワップに逃げていて、どこが空白地帯になっているか(正
確には、共有メモリ空間とか、ディスクキャッシュとか、shmfs 等の RAMディ
スクもある)は、ユーザプロセスからは見えません。仮想メモリ、というくら
いなので、わかっちゃまずいんですが。裏でカーネルが按配よく手配してくれ
ているのです。
ただ、カーネルについては、必ず常に実メモリに載っていて、どのプロセスの
セグメントにも現れている、という特性があります。
> そもそも、「実際に取ってみる」ってどうなのでしょう?
というわけで、裏でカーネルがこれだけの仕事をやっている以上、「実際に取っ
てみる」というのは、「とりあえず実メモリをかき集めてきて mmap か heap
に貼り付ける」というだけの話なので、何ら意味はないことになりますよね。
もっとも、経験上、malloc() 1回で取れるメモリブロックは、とりあえず全部
実メモリに載っていて、かつ、物理アドレスとして連続しているんじゃないか、
と思っています(嘘かも)。
# 例えば、2G 一気に malloc() できなくても、1G ずつ 2回だとよかったり、
# 1M ずつなら 2700回以上 OK だったりするので。まぁ、この場合は古いブロッ
# クはスワップに押し出されるんでしょうけど。
実際には、実メモリにはカーネルが居座ってますし、スタックもそう簡単にス
ワップアウトしませんので、相当数目減りします。また、他のプロセスが動い
ている以上、その分にぽつぽつ食われる部分があって、どうしても連続領域を
確保するのは大変みたいです。
> 実際にallocateされてしまうと、他のprocessにとっては無いも
> 同然なわけで、例えば、
これもちょっと違うんですよね。あるプロセスが malloc() してぎってきても、
他のプロセスで必要になれば、剥されてスワップに出されるかもしれません。
あるないの問題ではなくて、プロセスからは本当に意識できないんですよ。
スワップの状態はカーネルが内部で管理してます。実際にはそこのアドレスに
はメモリが載っていない状態ですが、ここに CPU がアクセスするとメモリフォ
ルトが発生して、カーネルが仕事(メモリマップを見て、スワップにあれば戻
すし、本当になければ SEGV を送る)を始めます。
> それでも、実際にRAM限定でallocしてみるのであれば、malloc
> する前に、mlockall(2)を使って、
>
> mlockall(MCL_FUTURE);
>
> とかすると、良いかも知れません。
あー、これはいいですね。あいかわらずスワップはメモリを圧迫してくれます
けど。あと、malloc するのであれば、128KB 以上のブロックでとってあげた
方がいいです。このへんは、mmap と heap の使い方の癖に関わってくるんで
すが。
# まぁ、実メモリが 1G を超えない限りはここが問題になることはないのです
# が :-)
> | printf("\n chk-ram ms=%d, v=%d", ms, v);
> | if(mlockall(MCL_FUTURE)){printf("mlockall error!\n"); exit(1)} <---
> |
> | i = check_ram_size(ms, v);
> | printf("\n check_ram_size (result): %d[MB]\n", i);
>
> と一行いれ、ついでにmallocの直前にmalloc sizeを表示するprintf
> をいれて、RAM 1024M, SWAP 2GのPCで実行してみたところ、973Mま
> で行ったところで、daemonやらktermやらが落ちまくってしまい、
> コマンドの終了が見届けられませんでした。
これも、1GB の壁に当たってるように見えるので、その問題に関係してるんじゃ
ないかなぁ。ようするに、text+heap はメモリマップ上で 1G 分に制限されて
て、128KB 未満の malloc() はこちらからしか取らないのです。
大きいブロックは、その上の mmap + スタックの領域(2G)から取ってきます。
これが溢れると heap も使いますので、「取れるだけ取る」のであれば、
128KB でぎっていくのが正解。
> Subjectの「物理メモリサイズの取得」は、本文とニュアンスが違
> う気がしますが、Subject通りなら、/proc/meminfoやsysinfo(2)で
> わかるだろうと思います。
ですね。ユーザプロセスから関知できない以上、管理しているカーネルに聞く
のが正解ですよ。libgtop とか、xosview とか、GkRellm とか、このへんを実
装しているものはいくらでもあるので、教材には事欠かないと思います。
_______________________________
田原 俊一 jado@flowernet.gr.jp, shunichi_tahara@zenrin.co.jp
http://flowernet.gr.jp/jado/
FingerPrint: 16 9E 70 3B 05 86 5D 08 B8 4C 47 3A E7 E9 8E D9
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
- Follow-Ups
-
- [plamo:21938] Re: 物理メモリサイズを取得する方法を教えて下さい, Iwasa Dai
- References
-
- [plamo:21933] 物理メモリサイズを取得する方法を教えて下さい, H.Shiozaki
- [plamo:21934] Re: 物理メモリサイズを取得する方法を教えて下さい, Iwasa Dai
[検索ページ]
[メール一覧]
Plamo ML 公開システム