レポート作成時のメモリ使用量を軽減させる方法について

文書番号 : 24927     文書種別 : 使用方法     最終更新日 : 2010/02/18
文書を印刷する
対象製品
ActiveReports for .NET 3.0J Standard Edition
詳細
ActiveReports が使用したメモリは、通常、共通言語ランタイム(CLR)のガベージコレクタにより定期的に自動解放されます。この自動解放は、メモリが十分に余っている場合には実行されないため、解放のタイミングやレポートの構造によっては、一時的に使用メモリ量が増加し、OutOfMemoryException等の例外が発生する場合があります。

画像を含むレポートは、文字のみのレポートと比較すると、メモリ使用量が大きくなります。毎ページに同じ画像を出力した場合でも、ページ数に比例した量のメモリを使用します。画像の形式にもよりますが、画像をメモリ上に展開したときのサイズ(メモリ使用量)は、画像ファイル自体のサイズよりも大きくなります。
また、レポートを PDF等の形式でエクスポートする場合には、ActiveReports の標準形式で作成したレポートを PDF形式に変換するという処理になるため、Viewer 等でプレビューする場合などよりも、使用されるメモリ量は増加します。

ActiveReports を使用したアプリケーションのメモリ使用量を軽減させる方法や、パフォーマンスを向上させる方法としては、以下のような内容が考えられます。

  1. レポートの構造や処理を変更する
    レポートの構造や実装する処理の内容を変更することで、レポート作成時のメモリ使用量を低減できる場合がございます。
    詳細につきましては、製品ヘルプの以下の内容をご参照ください。

    ActiveReports for .NETユーザーガイド
     - ActiveReports for .NETの概要
      - クイックスタート
       - ActiveReportsの最適化
     - よくある質問
      - その他
       - メモリが大量に消費される場合の対応方法

  2. コントロール数を減らす
    レポート上にコントロールが多数配置されている場合、消費するメモリの量も大きくなります。
    たとえば、Lineコントロールで四角形を構成している場合には、Shapeコントロールで代用する方法や、Shapeコントロールで文字列に枠を出力している場合には、TextBoxやLabelの罫線(コントロール枠線)を使用するといった方法が考えられます。

  3. サブレポートを使用しない
    サブレポートはそれ自体が一つのレポートとして生成されるため、サブレポートを使用しないレポートと比較すると、メモリ消費量やパフォーマンスの面で劣る場合があります。
    レポートの構成にもよりますが、グループヘッダ/フッタセクションを利用することや、レポートにセットするデータソースの構成を変更することで、サブレポートを使用せずに同内容のレポートを実現できる場合もございますので、こちらの方法もご検討ください。

    グループヘッダ/フッタを使用してグループ化を行う方法につきましては、製品ヘルプの以下の内容をご参照ください。

    ActiveReports for .NETユーザーガイド
     - サンプルと基本操作
      - 目的別サンプルと基本操作
       - レポートをグループ化したい

  4. データソースの使用方法を変更する
    .NETアプリケーション全般の動作仕様になりますが、マイクロソフト社の以下のページにあります通り、DataReaderオブジェクトを使用した場合、DataSetオブジェクトへデータを読み取る場合に比べ、高いパフォーマンスを実現できることが確認されております。

    [第 12 章 「ADO.NET パフォーマンスの向上」]
    http://msdn.microsoft.com/ja-jp/library/ff647768.aspx

    非接続型のDataSetではなく、XXXDataReaderなどの接続型オブジェクトを使用するなどの方法で、メモリ使用量を軽減できる場合があります。具体的な方法につきましては、製品ヘルプの以下の内容をご参照ください。

    ActiveReports for .NETユーザーガイド
     - サンプルと基本操作
      - サンプル
       - Standardのサンプル
        - Bound
         - DataReaderのバインド サンプル
     - よくある質問
      - データベース
       - Oracle データ ソースを使用する
       - ODBC データ ソースを使用する

  5. Sessionに大きなサイズのデータを格納しない
    ActiveReportsと関係なく、一般的な内容になりますが、大きなサイズのデータをSessionオブジェクトに格納するような処理は、基本的に推奨されていません。
    アットマークアイティ社のWebサイトで公開されている、以下の情報をご参照ください。

    [@IT:.NETエンタープライズWebアプリケーション開発技術大全 Sessionオブジェクト]
    http://www.atmarkit.co.jp/fdotnet/entwebapp/entwebapp06/entwebapp06_03.html

    Sessionに大きなサイズのデータを格納している場合には、必要な情報のみをSession経由で受け渡すようにするなどの方法をご検討ください。

  6. パフォーマンス オプションを設定する
    Windowsのパフォーマンスオプションを設定することで、パフォーマンスを向上できる可能性が考えられます。こちらの方法をお試しください。

    [Windows XP のパフォーマンス オプションの設定方法]
    http://support.microsoft.com/kb/308417/ja

    [パフォーマンス オプションを設定する]
    http://technet2.microsoft.com/WindowsServer/ja/library/af077bfa-426c-4b76-be6a-c78d7228ce941041.mspx

  7. パフォーマンスに関する一般的な情報
    マイクロソフト社のWebサイトで公開されている以下の情報につきまして、ご確認ください。

    [.NET アプリケーションのパフォーマンス関連のヒントとトリック]
    http://msdn.microsoft.com/ja-jp/library/ms973839.aspx

    [ASP.NET のパフォーマンス]
    http://msdn.microsoft.com/ja-jp/library/44e5wy6k(VS.80).aspx

    [アプリケーション開発時のビルド]
    http://msdn.microsoft.com/ja-jp/library/9c4h5y3e(VS.80).aspx

    [.NET アプリケーションのパフォーマンスとスケーラビリティの向上]
    http://msdn.microsoft.com/ja-jp/library/ff647946.aspx

    [ASP.NET Web アプリケーションで System.OutOfMemoryException が発生する場合のトラブルシューティング]
    http://support.microsoft.com/kb/954830/ja

  8. 仮想プリンタの設定
    パフォーマンスとは直接関係ありませんが、Webアプリケーション上でレポートを作成する場合には、仮想プリンタの設定を行った上で、用紙サイズ・方向を設定されることをお勧めいたします。
    レポートの作成前に、PrinterクラスのPrinterNameプロパティに""を設定することで、仮想プリンタ機能を使用できます(この際、デザイナ上での用紙サイズは、「デフォルトプリンタ」に指定してください)。

    通常の場合、ActiveReportsは、レポート作成時に実行環境上のプリンタ(プリンタドライバ)から、用紙サイズ等の情報を取得します。
    仮想プリンタの設定を行った場合、実行環境上のプリンタからの情報取得を行わず、任意のサイズでレポートを作成します。そのため、情報取得のためのオーバーヘッド発生や、指定した用紙サイズをプリンタがサポートしていない場合に発生する問題を回避することが可能です。

    仮想プリンタは、レポートを生成する環境と表示・印刷する環境が異なるWebアプリケーションや、レポートをPDF等の形式にエクスポートする場合に有効となる方法です。

    ◆サンプルコード(VB.NET)
     Dim rpt As New ClassLibrary1.NewActiveReport1

     ' 仮想プリンタを設定します。
     rpt.Document.Printer.PrinterName = ""

     ' 用紙サイズをA4縦に設定します。
     rpt.PageSettings.PaperKind = System.Drawing.Printing.PaperKind.A4
     rpt.PageSettings.Orientation = _
      DataDynamics.ActiveReports.Document.PageOrientation.Portrait

     rpt.Run()

    ◆サンプルコード(C#)
     ClassLibrary1.ActiveReport1 rpt = new ClassLibrary1.ActiveReport1();

     // 仮想プリンタを設定します。
     rpt.Document.Printer.PrinterName = "";
     // 用紙サイズを A4縦 に設定します。
     rpt.Document.Printer.PaperKind = System.Drawing.Printing.PaperKind.A4;
     rpt.PageSettings.Orientaion
      = DataDynamics.ActiveReports.Document.PageOrientation.Portrait;

     // レポートを作成します。
     rpt.Run();

    また、製品ヘルプの以下の内容もあわせてご覧ください。

    ActiveReports for .NETユーザーガイド
     - ActiveReports for .NETの概要
      - アーキテクチャと概念
       - 仮想プリンタ

  9. 運用面での対処
    恐れ入りますが、運用面での対処につきましてもご検討ください。たとえば、以下のような対処方法が考えられます。
    • 処理を分割し、一度に作成・印刷するレポートのデータ量を減らす
    • ループ内で繰り返し使用するオブジェクト(PdfExportクラスなど)をループの外で宣言する
    • 不変部分は事前に生成してファイルに保存しておく
    • 出力データの編集等をイベント内では行わず、予めデータソースの内容を編集しておく
    • 実行環境の物理メモリや仮想メモリを増やす
関連情報
キーワード
HowTo

この文書は、以前は次のFAQ IDで公開されていました : 10826