CDC::DrawTextを使うとメモリ使用量が増えていく – プログラミング – Home

CDC::DrawTextを使うとメモ...
 
通知
すべてクリア

CDC::DrawTextを使うとメモリ使用量が増えていく


いしだ
 いしだ
(@いしだ)
ゲスト
結合: 18年前
投稿: 53
Topic starter  

VS2005でダイアログベースのテストアプリケーションを用意し、
ボタンクリックのハンドラの中に以下のようなテストルーチンを入れました。

void CAAAADlg::OnBnClickedButton1()
{
static int a = 10;
CClientDC dc(this);

LOGFONT logfont;
ZeroMemory(&logfont, sizeof(logfont));
logfont.lfHeight = a++;
logfont.lfCharSet = DEFAULT_CHARSET;

CFont font;
font.CreateFontIndirect(&logfont);
CFont* pFont = (CFont*)dc.SelectObject(&font);

dc.DrawText(_T(1), CRect(0, 0, 500, 500), 0);

dc.SelectObject(pFont);
font.DeleteObject();
}

ダイアログを表示させ、ボタン1上でEnterキーを押し続けると、
どんどん「1」の文字が大きくなっていきますが、
タスクマネージャ上のメモリ使用量もどんどん増えていきます。

なお、dc.DrawText()の部分をコメントアウトしたり、
フォントサイズ(a)を増やさずに同じ値のままにしておくと、
何度コールしても使用量は全く増えません。

なぜこららの関数を呼ぶだけでなぜ増えていくのでしょうか。
なにか解放し忘れているものがありますでしょうか?


引用解決済
トピックタグ
ITO
 ITO
(@ITO)
ゲスト
結合: 23年前
投稿: 1235
 

描画が終わってないのに再び
「void CAAAADlg::OnBnClickedButton1()」
が呼ばれるからでは?
フラグを設定するかして、描画が終わるまで再び
処理を行わないようにしないと駄目ですね。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 23年前
投稿: 1235
 

あと気になったので、
> static int a = 10;
staticを使わずにメンバー変数を使ったほうがいいのでは?

> logfont.lfHeight = a++;
どんどん増えてしまうよ......
if(a > ??) a = 0; ??は任意の値
等がいるのではないでしょうか?


返信引用
ー
 ー
(@ー)
ゲスト
結合: 18年前
投稿: 9
 

void CAAAADlg::OnBnClickedButton1()
{
static int a = 10;
CClientDC dc(this);

int id = dc.SaveDC() ;//ここ

LOGFONT logfont;
ZeroMemory(&logfont, sizeof(logfont));
logfont.lfHeight = a++;
logfont.lfCharSet = DEFAULT_CHARSET;

CFont font;
font.CreateFontIndirect(&logfont);
CFont* pFont = (CFont*)dc.SelectObject(&font);

dc.DrawText(_T(1), CRect(0, 0, 500, 500), 0);

dc.SelectObject(pFont);//問題はここでしょ

dc.RestorDC( id ) ; //ここについか

font.DeleteObject();


返信引用
ー
 ー
(@ー)
ゲスト
結合: 18年前
投稿: 9
 

ごめんちがったw
忘れてくださいw


返信引用
いしだ
 いしだ
(@いしだ)
ゲスト
結合: 18年前
投稿: 53
Topic starter  

> 描画が終わってないのに再び
> 「void CAAAADlg::OnBnClickedButton1()」
> が呼ばれるからでは?

Windowsのメッセージループ上、OnBnClickedButton1を抜けるまでは
再びOnBnClickedButton1に来ることは無いはずです。
実際、適当なタイミングでゆっくりとクリックし続けても
メモリ使用量は増え続けていきます。

なお、この現象はXP上で発生していたのですが、
さきほど同じプログラムを2000で試してみたところ、
メモリ使用量が増えることはありませんでした。
また、DrawTextの部分を

dc.TextOut(0, 0, _T(1));

とすると、XPでもメモリ使用量は増えませんでした。
XPのDrawTextって、なにか制限でもあるのでしょうか。

> staticを使わずにメンバー変数を使ったほうがいいのでは?
> どんどん増えてしまうよ......

もちろん、これはプロジェクト名からもわかるとおり、
一時的に用意したテストプログラムです。
別の本番プログラムでメモリ使用量が増え続ける問題があり、
いろいろ原因を探っていたところDrawTextの部分が怪しいことがわかり、
その部分だけに絞ってテストプログラムを作ってみたら同じ現象が出たため、
ここで質問させていただきました。


返信引用
a
 a
(@a)
ゲスト
結合: 24年前
投稿: 59
 

興味があり、少し検証してみました。
当方でも再現できました。

logfont.lfHeight = 20/*a++*/;
と20固定で実行すると全く増えませんね。
なんでしょうねぇ。


返信引用
a
 a
(@a)
ゲスト
結合: 24年前
投稿: 59
 

当然こんなことしても増える一方。
//デバッグ中にm_Dirを反転する
if(m_Dir){
logfont.lfHeight = a++;
}else{
logfont.lfHeight = a--;
}


返信引用
a
 a
(@a)
ゲスト
結合: 24年前
投稿: 59
 

パフォーマンスで観察するとPrivateBytes、
VirtualBytesがうなぎ登り・・・。


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> 別の本番プログラムでメモリ使用量が増え続ける問題があり、
> いろいろ原因を探っていたところDrawTextの部分が怪しいことがわかり、
> その部分だけに絞ってテストプログラムを作ってみたら同じ現象が出たため、

VC++2003, XPでも再現しました。

if (++a > 200) a = 10;

このようにして、タイマーで呼び出してみましたが、
メモリ使用量は一定の値以上には増えませんでした。
おそらく、フォントがキャッシュされているようなイメージだと思うのですが。

解放漏れではないと思いますので、そういうものだと割り切るのが楽ですが、
本番プログラムで、どのような不都合がありますか?
ありえないくらい多くのフォントを使うとか?


返信引用
いしだ
 いしだ
(@いしだ)
ゲスト
結合: 18年前
投稿: 53
Topic starter  

試していただき、ありがとうございます。

サイズをいじらないと増えないということは、
XPでは一度使ったフォントをOSがキャッシュしているのかなとも思うのですが、
このテストプログラムでEnterを押し続けていると、
平気でメモリ使用量が1GBとか超えていきます。

本番ではグラフィックエディタのようなものを作っており、
表示倍率の拡大縮小などを繰り返したりフォントを変更したりすると、
メモリ使用量がどんどん増えていくのです。
たしかに、OS自体がこの状態でも問題無く動いてくれるのならよいのですが、
これは正常な動きと報告してしまってもよいものなのでしょうか…。


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> たしかに、OS自体がこの状態でも問題無く動いてくれるのならよいのですが、
> これは正常な動きと報告してしまってもよいものなのでしょうか…。

怖いですね。
ちなみに、CView::OnDrawで同じようなコードを書いても再現しませんでした。
私では原因不明。私にできることはSDKで試すことと他の回答を待つ位か。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました