レポート作成時のメモリ使用量を軽減させる方法について
対象製品
ActiveReports for .NET 3.0J Standard Edition
詳細
ActiveReports が使用したメモリは、通常、共通言語ランタイム(CLR)のガベージコレクタにより定期的に自動解放されます。この自動解放は、メモリが十分に余っている場合には実行されないため、解放のタイミングやレポートの構造によっては、一時的に使用メモリ量が増加し、OutOfMemoryException等の例外が発生する場合があります。
画像を含むレポートは、文字のみのレポートと比較すると、メモリ使用量が大きくなります。毎ページに同じ画像を出力した場合でも、ページ数に比例した量のメモリを使用します。画像の形式にもよりますが、画像をメモリ上に展開したときのサイズ(メモリ使用量)は、画像ファイル自体のサイズよりも大きくなります。
また、レポートを PDF等の形式でエクスポートする場合には、ActiveReports の標準形式で作成したレポートを PDF形式に変換するという処理になるため、Viewer 等でプレビューする場合などよりも、使用されるメモリ量は増加します。
ActiveReports を使用したアプリケーションのメモリ使用量を軽減させる方法や、パフォーマンスを向上させる方法としては、以下のような内容が考えられます。
画像を含むレポートは、文字のみのレポートと比較すると、メモリ使用量が大きくなります。毎ページに同じ画像を出力した場合でも、ページ数に比例した量のメモリを使用します。画像の形式にもよりますが、画像をメモリ上に展開したときのサイズ(メモリ使用量)は、画像ファイル自体のサイズよりも大きくなります。
また、レポートを PDF等の形式でエクスポートする場合には、ActiveReports の標準形式で作成したレポートを PDF形式に変換するという処理になるため、Viewer 等でプレビューする場合などよりも、使用されるメモリ量は増加します。
ActiveReports を使用したアプリケーションのメモリ使用量を軽減させる方法や、パフォーマンスを向上させる方法としては、以下のような内容が考えられます。
- レポートの構造や処理を変更する
レポートの構造や実装する処理の内容を変更することで、レポート作成時のメモリ使用量を低減できる場合がございます。
詳細につきましては、製品ヘルプの以下の内容をご参照ください。
ActiveReports for .NETユーザーガイド
- ActiveReports for .NETの概要
- クイックスタート
- ActiveReportsの最適化
- よくある質問
- その他
- メモリが大量に消費される場合の対応方法
- コントロール数を減らす
レポート上にコントロールが多数配置されている場合、消費するメモリの量も大きくなります。
たとえば、Lineコントロールで四角形を構成している場合には、Shapeコントロールで代用する方法や、Shapeコントロールで文字列に枠を出力している場合には、TextBoxやLabelの罫線(コントロール枠線)を使用するといった方法が考えられます。
- サブレポートを使用しない
サブレポートはそれ自体が一つのレポートとして生成されるため、サブレポートを使用しないレポートと比較すると、メモリ消費量やパフォーマンスの面で劣る場合があります。
レポートの構成にもよりますが、グループヘッダ/フッタセクションを利用することや、レポートにセットするデータソースの構成を変更することで、サブレポートを使用せずに同内容のレポートを実現できる場合もございますので、こちらの方法もご検討ください。
グループヘッダ/フッタを使用してグループ化を行う方法につきましては、製品ヘルプの以下の内容をご参照ください。
ActiveReports for .NETユーザーガイド
- サンプルと基本操作
- 目的別サンプルと基本操作
- レポートをグループ化したい
- データソースの使用方法を変更する
.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 データ ソースを使用する
- Sessionに大きなサイズのデータを格納しない
ActiveReportsと関係なく、一般的な内容になりますが、大きなサイズのデータをSessionオブジェクトに格納するような処理は、基本的に推奨されていません。
アットマークアイティ社のWebサイトで公開されている、以下の情報をご参照ください。
[@IT:.NETエンタープライズWebアプリケーション開発技術大全 Sessionオブジェクト]
http://www.atmarkit.co.jp/fdotnet/entwebapp/entwebapp06/entwebapp06_03.html
Sessionに大きなサイズのデータを格納している場合には、必要な情報のみをSession経由で受け渡すようにするなどの方法をご検討ください。
- パフォーマンス オプションを設定する
Windowsのパフォーマンスオプションを設定することで、パフォーマンスを向上できる可能性が考えられます。こちらの方法をお試しください。
[Windows XP のパフォーマンス オプションの設定方法]
http://support.microsoft.com/kb/308417/ja
[パフォーマンス オプションを設定する]
http://technet2.microsoft.com/WindowsServer/ja/library/af077bfa-426c-4b76-be6a-c78d7228ce941041.mspx
- パフォーマンスに関する一般的な情報
マイクロソフト社の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
- 仮想プリンタの設定
パフォーマンスとは直接関係ありませんが、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の概要
- アーキテクチャと概念
- 仮想プリンタ
- 運用面での対処
恐れ入りますが、運用面での対処につきましてもご検討ください。たとえば、以下のような対処方法が考えられます。
- 処理を分割し、一度に作成・印刷するレポートのデータ量を減らす
- ループ内で繰り返し使用するオブジェクト(PdfExportクラスなど)をループの外で宣言する
- 不変部分は事前に生成してファイルに保存しておく
- 出力データの編集等をイベント内では行わず、予めデータソースの内容を編集しておく
- 実行環境の物理メモリや仮想メモリを増やす
関連情報
キーワード
HowTo
この文書は、以前は次のFAQ IDで公開されていました : 10826