[BlueLeaf1336]> PROBLEMS> メモリクリーナー SusieQ>

メモリクリーナー SusieQ > メモリクリーナーのシクミ

historyTOP

2005/05/04:作成

2005/05/04TOP

今はWindows2000を使っているんですが、以前はWindows98を使っていました。もう5年ぐらい前になるような...この時からずぅっと常駐しつづけているのソフトがあって、それが、CareTakerという物理メモリ管理ツール(ヘルプより)です。ところが作者のサイトに行ってももはやサポートを止めているようないないような感じで、おまけにWindows2000にしてからそれほど使ってもいず、主に「最近使ったファイルのクリア」(タスクトレイアイコンの右クリックですばやく手軽に実行できるんです)のためだけに常駐させているような具合になってきています。

さて、物理メモリ管理ツールを作ってみようと思ったわけです。はっきりいって怖くて怖くてそんなプログラム作ったところで使う気になりませんが、原理はとても簡単なようです。

の説明書を読むと、非常にわかり易く説明されているのですが、簡単にまとめると、Windowsに対して使いもしないメモリ領域を要求して、他のプログラムが今後のために溜め込んでいる領域を無理やり搾取して、搾り取るだけ搾り取ったらばさっとWindowsに返す。するとその要求した分だけの空きがとりあえずできる、と、そういうことらしいです。

実際テキストエディタのPeggyPadを1つ起動すると4500KBほど確保してますが、コレを50個ぐらい同時に起動するとそれぞれが4500KBも確保しつづけることなんてよほどのことがない限り無理な話ですが、ちゃんと50個ぐらい同時に起動します。このとき最初に起動したPeggyPadの使用メモリをタスクマネージャーで見てみるとすっごく少なくなってます。100KBぐらいだったか。今やってみるとそんなこと全くないですね。みんな4500KBを確保したまま50個ぐらい起動してます。物理メモリが380MB以上あるからでしょうか。

いずれにしてもそういうわけです。ここで実際の処理と行きたいところですが、実は...

こんなすばらしいサイトがありまして、しかも「最終更新日 1999/12/12」です。ただこのサイトのはVisualBasicですので、ここではDelphiで書くということで許してもらうことにします。

メモリクリーナーメイン処理TOP

procedure TForm1.Button1Click(Sender: TObject);
var
    AllocPointer: Pointer;  //  確保したメモリのアドレス
    dwSize: DWORD;          //  確保するサイズ
begin
    //  確保するサイズを指定する
    dwSize := 32 * 1024 * 1024; //  32MB
    //  Windowsに要求する
    AllocPointer := VirtualAlloc(nil, dwSize, MEM_COMMIT, PAGE_READWRITE or PAGE_NOCACHE);
    //  実際にアクセスしないとだめ(?)
    FillMemory(AllocPointer, dwSize, 0);
    //  即刻解放する
    VirtualFree(AllocPointer, dwSize, MEM_DECOMMIT);
end;

ちょっとひとことTOP

上のサイトの参考コードをほぼそのままDelphiに直しただけのものです。他には以下のサイトを参考にしました。

それから、Windows.pasから

  PAGE_READWRITE = 4;
  PAGE_NOCACHE = $200;
  MEM_COMMIT = $1000;
  MEM_RELEASE = $8000;

以上の定数値を見て、VB版の定数値に置き換えました。さらにそれから

の以下のレスをみて「実際にアクセスしないとだめ(?)」というコメントにたどり着いています。そんなこといわなくても、VBのサイトの説明に「ちゃんとアクセスしないとだめ」とかいてあるんですが...

839 名前: SHEZ 投稿日: 02/03/23 20:24
メモリクリーナーって大量にメモリを確保して、解放してやればいいんですか・・?
GlobalAlloc(GPTR,128*1024*1024)みたいに確保してGlobalFree()で解放しても、あまり変わらなかったような・・
本場のやつではあんな長い時間何やっているんでしょうか・・^^;

840 名前: 超先生@プログラム板 投稿日: 02/03/23 21:33
>>839
  ∧_∧
< `ш´>y-~~~ メモリクリーナーってのは難しいところだが。
GlobalAllocだと確保したメモリ空間へ実際にアクセスするまで物理メモリは割り当てられないのだ。(demand-paging)
そこで、確保したメモリへプロセッサのページ(4KB)ごとにダミーの読み書きをしてみたらどうかな。
上手くいけば物理メモリが割り当てられ、解放すると同時に物理メモリが空くはずだ。
ちなみにVirtualAllocにMEM_COMMIT|MEM_PHYSICALを指定して呼び出すと
強制的に物理メモリをコミットしてくれるみたいだ。(NT系限定だが)

841 名前: 821 投稿日: 02/03/23 21:47
>>823
回答をありがとうございました
なにかすごいのがないかなと思ったのですが…。甘かったですか。
purifyと自力で頑張ります。

151 名前: こんぱる 投稿日: 02/03/23 20:28
メモリクリーナーって大量にメモリを確保して、解放してやればいいんですか・・?
GlobalAlloc(GPTR,128*1024*1024)みたいに確保してGlobalFree()で解放しても、あまり変わらなかったような・・
本場のやつではあんな長い時間何やっているんでしょうか・・^^;

152 名前: デフォルトの名無しさん 投稿日: 02/03/23 20:28
>>151
virtualallocじゃなかったっけ?

154 名前: こんぱる 投稿日: 02/03/23 20:31
おぉ、Help見てみましたが、そのようです..
メモリの確保ときたらGlobalAllocとかmallocしか知りませんでした・・
ありがとうございます。

155 名前: デフォルトの名無しさん 投稿日: 02/03/23 20:32
>>151
実際にアクセスしないと駄目だよ

156 名前: こんぱる 投稿日: 02/03/23 20:34
予約してから、解放する・・ですか?
コミット状態にする・・??
コミットってなんや・・?なんかFFにでてきそうなんですが。

158 名前: こんぱる 投稿日: 02/03/23 20:43
VirtualAllocで検索したらいろいろと出てきました。
ありがとうございました。

こんな感じTOP

128MB程を掃除するのに2秒ほどかかっています。やはりここは掃除中であることをかっこよくアピールすべきと思われます。

20050504SusieQTest.zip(2,222bytes)

その他TOP

こんなページもありました。HSPですが。

ところで、「掃除中であることをかっこよくアピール」と書いたばかりですが、FillMemoryがどれだけ進んでいるのかなんて全くわからないので、プログレスバーの表示は厳しいです。となると、うーん。

「SusieQ」は「掃除」「そうじ」「そーじ」「ソージ」「ソージー」(あ、ジョジョ)「スージーQ」(スージーの綴りって...Susie)「SusieQ」です。ですが、あのあまりにも有名な「Susie」と「Q」があるかないかだけの違いなんて恐れ多くて駄目な気がしてきました。

でも...今Googleで「Susie」を検索してみると「Susie の検索結果のうち 日本語のページ 約 92,200 件中 1 - 10 件目 (0.05 秒) 」なんてことになってるので、ここに1ページぐらい加わったところで誰も何も気づきもしないだろうか、どうだろうか。でもやっぱりなぁ。大丈夫か。

EOFTOP