[pgsql-jp: 40491] Re: 仮想メモリが解放されない

Hiroshi Inoue inoue @ tpf.co.jp
2010年 11月 2日 (火) 08:39:23 JST


井上です。

(2010/11/01 11:41), 錦戸 暖 wrote:
> (2010/10/29 14:32), 錦戸 暖 wrote:
>> (2010/10/29 14:09), Itagaki Takahiro wrote:
>>> つまり、アプリ側でのメモリリークをデバッグする話になる ので、 がん
>>> ばってくださいとしか言えません。ADO の使い方であれば、 この MLでも誰
>>> かが答えてくれるかもしれませんが…。 また、一般的な話ですが、仮 想メモ
>>> リのリークって、本当に メモリリークなんでしたっけ? free() した 仮想
>>> アドレスが 返却するか否かは、Cランタイムの作りに依存していたはずで
>>> す。 該当の処理を繰り返してみて、本当に修正が必要なリークなのか 確認
>>> す るのが先決なのでは。
>> ご返信ありがとうございます。
>> 調査致します。
>>
>>
> 調査した結果、以下のような単純なプログラムを実行した場合も
> 確保した仮想メモリが減少しないことがわかりました。
> ------------------------------------------------------------------
> // COMの初期化
> CoInitalizeEx(NULL, COINIT_MULTITHREADED)
>
> // コネクションの取得
> _ConnectionPtr c;
> c.CreateInstance(_T("ADODB.Connection"));
> c.->Open(/*接続文字列*/,/*ユーザID*/,/*パスワード*/,adConnectUnspecified);
>
> // レコードセットポインタの取得
> _RecordsetPtr r;
> r.CreateInstance(_T("ADODB.Recordset"));
> r->CursorLocation = adUseClient;
>
> // SQL実行
> r->Open(/*SQL文(SELECT)*/, _variant_t(IDispatch)c, true);
>
> // レコードセットのクローズ
> r->Close();

ちゃんと調べたわけではないので断言はできませんが、普通に考えれば
ドライバはSELECTで取得したデータをこの時点でfree()してしまうので、
コネクションプーリングによるリークはあったとしてもそんなに大きい
ものではないという気がします。
対応するにはドライバ側のメモリ管理の実装をmalloc/freeでないものに
変える必要があるかもしれません。

> r->Release();
> r=NULL;
>
> // コネクションのクローズ
> c->Close();
> c->Release();
> c = NULL;
>
> // COMの終了処理
> ::CoUninitalize();
> ------------------------------------------------------------------
>
> SELECT文により取得したデータのために確保された仮想メモリ使用量が
> レコードセット、コネクションのクローズ後も確保されたままとなるのですが、
> この現象は当然のことなのでしょうか?
> 上記処理繰り返すと仮想メモリ使用量が徐々に増加してしまい、仮想メモリ
> オーバーが発生します。
> ※ADOの使い方の質問になっているかもしれません。どなたかご存知の方、
> ご教授頂けると幸いです。
>
> DB接続オプションとして"UseDeclareFetch=1"を設定すると物理メモリ使用
> 量の増加に伴なう仮想メモリ使用量の増加を抑制することができるのですが、
> 今回この"UseDeclareFetch=1"を設定せずに処理を実施したいため、コネク
> ションをクローズした時点で仮想メモリ使用量をコネクションのオープン時点
> に戻したいのですが。。。
>
> 以上、よろしくお願い致します。



pgsql-jp メーリングリストの案内