削除またはフィルタバッファにデータがある状態で検索やリセットを行うとメモリリークする

バグ情報

データウィンドウの削除バッファおよびフィルタバッファにデータが存在する状態で Retrieve 関数や Reset 関数を呼び出すと、メモリが解放されなくなる事象が報告されています。

Bug ID 7786
Product PowerBuilder EN/JP
ステータス Appeon にて検証中
発生バージョン EN 12.6以前 2017 (R2) 2017 (R3) 2019 2021
JP 12.6以前 2017 (R2) 2017 (R3) 2019

:発生バージョン   :解決済み、未発生   :未確認

(2017 以外のバージョンについてはリリースされている最新リビジョンでの状況です)

 

詳細

データウィンドウのフィルタ設定や Filter 関数などによってフィルタバッファにデータ行を移動した場合や、DeleteRow、RowsMove 関数によってデータを削除し削除バッファに移動した場合など、フィルタバッファおよび削除バッファにデータが存在する状態で Retrieve 関数や Reset 関数を呼び出すと、それらのデータが破棄されるにもかかわらずメモリが解放されないため、ウィンドウを閉じずに検索を何度も行うような処理ではメモリ使用量が増大するおそれがあります。

なお、それぞれのバッファにデータが残った状態で Retrieve 関数、Reset 関数を呼び出した場合、データオブジェクトの変更やウィンドウを閉じるなどの方法でデータウィンドウコントロールやデータストアオブジェクトが破棄されない限りメモリは解放されません。

 

回避策

  • フィルタバッファ、削除バッファのデータを破棄する
    • RowsDiscard 関数を利用してフィルタバッファ、削除バッファのデータを破棄してから検索/リセットしてください。
      // 削除バッファの全データを破棄
      dw_1.RowsDiscard(1, dw_1.DeletedCount(), Delete!)
      
      // フィルタバッファの全データを破棄
      dw_1.RowsDiscard(1, dw_1.FilteredCount(), Filter!)
      
      // 検索
      dw_1.Retrieve()
  • データオブジェクトを再設定する
    • データオブジェクトを再設定してデータウィンドウを初期化します。検索を行う場合はトランザクションオブジェクトも再設定する必要があります。
      // データオブジェクトを再設定
      dw_1.dataobject = dw_1.dataobject
      
      // トランザクションを設定
      dw_1.SetTransObject(SQLCA)
      
      // 検索
      dw_1.Retrieve()
  • フィルタを一度解除する (※フィルタバッファのみ)
    • SetFilter 関数、Filter 関数でフィルタを解除し、すべてのデータが主バッファにある状態で検索/リセットしてください。
      string ls_filter
      
      // 現在のフィルタ条件を取得
      ls_filter = dw_1.object.datawindow.table.filter
      
      // フィルタ条件が設定されている場合
      IF ls_filter <> "" THEN
          // フィルタを解除
          dw_1.SetFilter("")
          dw_1.Filter()
      
          // リセット
          dw_1.Reset()
      
          // フィルタ条件を再設定
          dw_1.SetFilter(ls_filter)
      END IF
      
      // 検索
      dw_1.Retrieve()
      
バグ情報 一覧を見る
PowerBuilder マイグレーション
PowerBuilder学習、動画で始めちゃう?