JVGetsで取得したByte型配列のレコードは使い終わったら消去する

前のポストSet object = Nothingを書かないとメモリがリリースされないで書いたようにオブジェクト消去をするようにしても、完全にはExcelプロセスのメモリ使用量が一定になりませんでした。Set object = Nothingを書かない場合よりはメモリ使用量が増えないのですが、増えたり減ったりしながら、だんだんメモリ使用量が増えていきます。

Excelのプロセスのメモリ使用量の時間変化を見ていると、JVLinkを扱うプロシージャのどこかでメモリリリースがされていないようでした。考えていたら、JVLink仕様書[1]JVGets()メソッドの説明を思い出しました。JVLink ActiveXコントロールはJVGetsの引数のレコードを代入するByte型配列は消去しないんでした。

そこで、JVDataのレコードを取得するJVGetsを使うときの擬似コードを次のようにしました。

Dim buff() as Byte
Do 最後のレコードまで
  Erase buff              ' Byte型配列を消去する
  JVLink.JVGets(buff)     ' レコードのポインタをbuffに代入する
  JVData.Record.Add buff  ' レコードを別のオブエジェクトに蓄積する
Loop 

Erase buffのコードをJVGetsの前に加えたら、メモリ使用量が一定になりました。Excelプロセスは起動したては80MBほどのメモリを使用しています。JVDataのレコードを取得、処理、データベース保存のサイクルでメモリ使用量が80MBから150MBほどに上がり、80MBに戻ります。

Erase buffJVGets()の前ではなく、レコードを蓄積した後に書くと、JVGets()がエラーを出した場合に、buffが残っていて再度JVGets()をコールしてしまうことが考えられるます。ですので、JVGetsの前にErase buffを書きました。


  1. 競馬ソフト開発 ソフトウェア開発キット提供コーナー - JRA-VANにpdfファイルがあります。 ↩︎

Kosuke Maeda / まえだこうすけ

「機械学習で競馬予想して勝てるのか?」をテーマに活動中! QiitaにはR、VBAなどのTipsを投稿しています。