MFC
メモリ常駐量を激減させる
※ 情報提供者:Vivas 様

HomeProgramming TipsMFC Tips[MFC-013]

常駐型プログラムにとって消費メモリ量を削減することは必須事項です。
いくらメモリが安くなったからといって、使うメモリは少ないほど良いに決まっています。
金持ちほどケチと同じ事です(違うって)。

さて、私が色々試していてもなかなか劇的な変化が起きず困っていたときに
掲示板で Vivas 様がテクニックを教えてくださいました。それはまさに天の声!

 WM_MINIZIEでメモリが開放されます

実は最初、全然減らなかったのですが、その設定手順を教えていただき実現できました。
それを MFC のプログラムとして改造したのが、今回公開する常駐メモリ量減少ワザです。
実際、意味があるかどうかよりも「すぱぱーん」と激減するメモリに魂が揺さぶられること必至です。

前提条件として、そのウィンドウはコールバックやメッセージを処理するために存在し、
実際のウィンドウ表示はしない事です。ウィンドウを表示させるとメモリは減りません。
※ 実際には普通にウィンドウを作るより減ります。この辺りは自分で試してみてください。

まず、CWnd を継承して自分独自のウィンドウクラスとします。ここでは CMyWnd とします。
とりあえず、クラスの作成 → 一般クラスとして作るのが良いです。
その CMyWnd のコンストラクタでウィンドウを作成します。
クラス名以外の全ての項目を 0 にしてしまいます。
そして、その後、隠してから最小化します。



// ---------------------------------------------------------------------
// クラス定義
// ---------------------------------------------------------------------
class CMyWnd : public CWnd
{
    DECLARE_DYNAMIC(CMyWnd)

public:
    CMyWnd();
    virtual ~CMyWnd();
};



// ---------------------------------------------------------------------
// コンストラクタ
// ---------------------------------------------------------------------
IMPLEMENT_DYNAMIC(CMyWnd, CWnd)
CMyWnd::CMyWnd()
{
    LPCTSTR lpszClassName = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
    if (CreateEx(0, lpszClassName, NULL, 0, 0,0,0,0, NULL, NULL, NULL)){
        ShowWindow(SW_HIDE);
        UpdateWindow();
        ShowWindow(SW_MINIMIZE);
    }
}


実は、これだけでは一瞬、タスクバーにウィンドウ生成が見えてしまいます。
これを見えなくするために OnWindowPosChanging() をオーバーライドします。


// ---------------------------------------------------------------------
// 表示は必ず消す
// ---------------------------------------------------------------------
void CMyWnd::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
    CWnd::OnWindowPosChanging(lpwndpos);

    // TODO : ここにメッセージ ハンドラ コードを追加します。
    lpwndpos->flags &= ~SWP_SHOWWINDOW;
    lpwndpos->flags |= SWP_HIDEWINDOW;
}


SW_MINIMIZE されることによりデバイスコンテキスト回りのメモリ確保分が捨てられるようです。
但し、これだけでは徐々に消費メモリが増えていくという現象が起きます。
これをある程度防止するためには、何かアクションを起こす度に


    ShowWindow(SW_MINIMIZE);


…を、実行します。その都度不要なメモリが捨てられて元の省メモリに戻ります。
OnWindowPosChanging() の処理のおかげで何があってもウィンドウは表示されません。
気軽に ShowWindow(SW_MINIMIZE); としてしまえば OK です。



 Copyright 2005 VALGUS. All Rights Reserved.