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

錦戸 暖 d-nishikido @ eandm.co.jp
2010年 11月 5日 (金) 09:35:03 JST


  お世話になっております。錦戸です。

2010/11/04 18:43), Hiroshi Inoue wrote:
> (2010/11/04 17:57), 錦戸 暖 wrote:
> 井上です。
>
>> お世話になっております。錦戸です。
>> (2010/11/04 17:34), Hiroshi Inoue wrote:
>>> (2010/11/04 9:28), 錦戸 暖 wrote:
>>>> (2010/11/03 8:26), Hiroshi Inoue wrote:
>>>>> 井上です。
>>>>>
>>>>>> 調査した結果、以下のような単純なプログラムを実行した場合も
>>>>>> 確保した仮想メモリが減少しないことがわかりました。
>>>>>> ------------------------------------------------------------------
>>>>>> // 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();
>>>>>> r->Release();
>>>>>> r=NULL;
>>>>>>
>>>>>> // コネクションのクローズ
>>>>>> c->Close();
>>>>>> c->Release();
>>>>>> c = NULL;
>>>>>>
>>>>>> // COMの終了処理
>>>>>> ::CoUninitalize();
>>>>>> ------------------------------------------------------------------
>>>>>>
>>>>>> SELECT文により取得したデータのために確保された仮想メモリ使用量が
>>>>>> レコードセット、コネクションのクローズ後も確保されたままとなるので
>>>>>> すが、
>>>>>> この現象は当然のことなのでしょうか?
>>>>>> 上記処理繰り返すと仮想メモリ使用量が徐々に増加してしまい、仮想メモリ
>>>>>> オーバーが発生します。
>>>>>
>>>>> こちらで簡単なケースを試してみましたが再現しません。何度位繰り返すと
>>>>> 発生するのでしょうか?
>>>> 以下のようなデータをSELECTした場合ならば、1度SQLを発行し終えた時点で
>>>> 発行前の仮想メモリ使用量までは減少しません。
>>>> レコード数:231427レコード
>>>> 1レコードのバイト数:327バイト
>>>
>>> 一度割り当てた仮想メモリが解放されないのは、当然と言い切る自信は
>>> ありませんが、不思議ではないと思います。私がお聞きしたかったのは
>>> 何度位繰り返すと仮想メモリオーバーになるのかということでした。
>>> 結構手間がかかるので、こちらのテストでは3~40回でやめています。
>>>
>> 上記のレコードを取得するSQLを2回実行した時点でメモリオーバーします。
>
> 2度目で発生するということは1度目で既にかなりぎりぎりの所まで
> 仮想メモリを消費しているということでしょうね。これって少し状況
> が変わると(たとえば件数が増えるとか)1度目でオーバーしてしま
> う可能性があると思うのですが大丈夫なんでしょうか?
SQLで取得するレコード状況が誤っていましたので訂正致します。
レコード数:2823698レコード
1レコードのバイト数:1369バイト

仰るとおり、上記SQLの場合は1度目で既にぎりぎりの所まで仮想メモリを消費
致します。1度目でオーバーすることも有り得ますがそういったSQLは分割して
取得するなど対応したいと考えています。
しかし、仮想メモリが開放されないと分割して取得することもできません。

参考までに本現象を発見した際のSQLによるレコード取得状況を以下に示します。
SQL1)レコード数:6、1レコードのバイト数:80
SQL2)レコード数:2314130、1レコードのバイト数:78
SQL3)レコード数:2314127、1レコードのバイト数:327
SQL4)レコード数:902469、1レコードのバイト数:583
SQL5)レコード数:2823698、1レコードのバイト数:1369
上記SQLを順に流していきますとSQL5で異常終了しました。

以上です。
>
>> 実行環境は以下の通りです。
>> 使用可能実メモリ:1.2G
>> 使用可能仮想メモリ:1.6G
>
>
>


-- 
//--------------------------------------------
// イー・アンド・エム株式会社
// 福岡開発本部 福岡開発センターグループ
// 錦戸 暖
// d-nishikido @ eandm.co.jp
// 080-5286-0985
//--------------------------------------------



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