C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[12]: 帳票出力時、メモリエラーが発生


(過去ログ 91 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■53877 / inTopicNo.1)  帳票出力時、メモリエラーが発生
  
□投稿者/ セプト (1回)-(2010/09/28(Tue) 22:57:53)

分類:[VB.NET/VB2005 以降] 

初めましてセプトと申します。

開発環境は以下の通りです。
OS:WindowsXP
DB:Access

開発言語:VB.NET 2008
     .NET FrameWork 3.1

itextを使用し、CrystalReportでPDFファイルの帳票を出力しています。
DBに存在する全てのデータを出力しますが、そのデータがだいたい2000件あります。

1レコード1ページの割合で出力しますが、出力するPDFファイルは1ファイルのみという仕様です。

処理の順序として全データを1ページずつ(1ファイルずつ)のPDFファイルにしてTempフォルダに出力し、
全件出力後PDFファイルを1つのファイルに結合します。

この処理を行うとメモリエラーが発生いたします。
エラー内容:'System.OutOfMemoryException'の例外がスローされました。

発生する箇所は出力したPDFファイルを1つのファイルに結合する処理で、
メモリがどんどん上昇しメモリエラーが発生いたします。

ただし、PDFファイルを2000件結合するだけだとメモリエラーは発生いたしません。
試しにデータを出力せず、TempフォルダにPDF2000ファイルを置いて処理を行ったところ正常終了しました。

調査の結果、CrystalReportの機能で必要となる以下の1行の変数を宣言すると
メモリエラーが発生するようです。

-----------------------
Dim oRpt As New cryBlockCa()
-----------------------

処理の中ではこの変数のメモリを解放するためにClose,Nothing等の処理を入れております。
以下 処理のプログラムの一部です。
※dtlOutputPageは帳票に出力されるデータが格納されたDataTableになります。
-----------------------
        Dim oRpt As New cryBlockCa()
        Dim optReport As New CrystalDecisions.Shared.DiskFileDestinationOptions()
        Dim FileControl As FileControl

        oRpt = New cryBlockCa
        oRpt.SetDataSource(dtlOutputPage)

        'レポート出力先
        optReport.DiskFileName = strFilePath

        'レポートの出力形式を決定
        oRpt.ExportOptions.DestinationOptions = optReport
        oRpt.ExportOptions.ExportDestinationType = CrystalDecisions.Shared.ExportDestinationType.DiskFile
        oRpt.ExportOptions.ExportFormatType = CrystalDecisions.Shared.ExportFormatType.PortableDocFormat

        oRpt.Export()   'レポート出力

        FileControl = New FileControl(optReport.DiskFileName)
        FileControl.SetFileAuthority()

        optReport = Nothing
        FileControl = Nothing

        oRpt.Close()
        oRpt.Dispose()
        oRpt = Nothing

        oRpt.Close()
        oRpt.Dispose()
        oRpt = Nothing
-----------------------
エラーの発生箇所はつかめておりますが、エラー原因がつかめておらず修正の目処が立っておりません。
CrystalReportの問題なのかVB.NETの問題なのかわかりませんでしたのでここで質問いたしました。

どなたか今回の現象に心当たりのある方がおられましたら、是非ご教授ください。

引用返信 編集キー/
■53879 / inTopicNo.2)  Re[1]: 帳票出力時、メモリエラーが発生
□投稿者/ 魔界の仮面弁士 (1842回)-(2010/09/28(Tue) 23:27:01)
No53877 (セプト さん) に返信
> 開発言語:VB.NET 2008
>      .NET FrameWork 3.1
.NET Framework 3.1 というバージョンは無いはずです(XNA Framework 3.1 ならありますが)。
VB2008 をお使いなら、.NET Framework の選択肢は 2.0/3.0/3.5 のいずれかですね。


> Dim oRpt As New cryBlockCa()
「cryBlockCa」は、どのようなクラスなのでしょうか?(google ではヒットしませんでした)
また、ここで New したインスタンスは、どこで使われるのでしょうか?


> Dim optReport As New CrystalDecisions.Shared.DiskFileDestinationOptions()
> Dim FileControl As FileControl
> oRpt = New cryBlockCa
変数宣言時に New されたインスタンスを、使うことも Close することもせずに、
ここの New で生成した別のインスタンスを割り当てていますが、問題無いのでしょうか?
引用返信 編集キー/
■53910 / inTopicNo.3)  Re[2]: 帳票出力時、メモリエラーが発生
□投稿者/ セプト (2回)-(2010/09/30(Thu) 03:15:26)
No53879 (魔界の仮面弁士 さん) に返信
遅くなって申し訳ありません。セプトです。
魔界の仮面弁士 さん返信ありがとうございます。質問にお答えします。

> .NET Framework 3.1 というバージョンは無いはずです(XNA Framework 3.1 ならありますが)。
> VB2008 をお使いなら、.NET Framework の選択肢は 2.0/3.0/3.5 のいずれかですね。

申し訳ありません。私の認識違いでした。
ソースを確認した所.NET Framework 3.5 SP1でした。訂正いたします。

>>Dim oRpt As New cryBlockCa()
> 「cryBlockCa」は、どのようなクラスなのでしょうか?(google ではヒットしませんでした)
> また、ここで New したインスタンスは、どこで使われるのでしょうか?

申し訳ありません。私の記述漏れです。
CrystalReportで帳票を作成すると自動的に作成されるクラスと認識しております。
今回「BlockCa」という帳票を作成しているので、このクラス名になっているかと思います。

ココでNewしたインスタンスはおそらくCrystalReportで使用されていると思われます。


>>Dim optReport As New CrystalDecisions.Shared.DiskFileDestinationOptions()
>>Dim FileControl As FileControl
>>oRpt = New cryBlockCa
> 変数宣言時に New されたインスタンスを、使うことも Close することもせずに、
> ここの New で生成した別のインスタンスを割り当てていますが、問題無いのでしょうか?

ご指摘の通り問題かと思われます。
現在指摘された内容を修正し確認テストを行っております。

確認完了までもうしばらくお時間をいただきたいと思います。
確認が終わりましたらまた報告いたします。
引用返信 編集キー/
■54018 / inTopicNo.4)  Re[3]: 帳票出力時、メモリエラーが発生
□投稿者/ セプト (3回)-(2010/10/02(Sat) 16:48:28)
No53879 (魔界の仮面弁士 さん) に返信

たびたびすみません。セプトです。
>>Dim optReport As New CrystalDecisions.Shared.DiskFileDestinationOptions()
>>Dim FileControl As FileControl
>>oRpt = New cryBlockCa
>変数宣言時に New されたインスタンスを、使うことも Close することもせずに、
>ここの New で生成した別のインスタンスを割り当てていますが、問題無いのでしょうか?

魔界の仮面弁士 さんのご指摘通り余計な変数を削除しテストを行いましたが現象が改善されず、
メモリエラーが発生いたします。

削除したのは以下の2つです。
Dim FileControl As FileControl
oRpt = New cryBlockCa

修正したソースは以下のようになります。
-----------------------
    Dim oRpt As New cryBlockCa()
    Dim optReport As New CrystalDecisions.Shared.DiskFileDestinationOptions()

    oRpt.SetDataSource(dtlOutputPage)

    'レポート出力先
    optReport.DiskFileName = strFilePath

    'レポートの出力形式を決定
    oRpt.ExportOptions.DestinationOptions = optReport
    oRpt.ExportOptions.ExportDestinationType = CrystalDecisions.Shared.ExportDestinationType.DiskFile
    oRpt.ExportOptions.ExportFormatType = CrystalDecisions.Shared.ExportFormatType.PortableDocFormat

    oRpt.Export()   'レポート出力

    optReport = Nothing

    oRpt.Close()
    oRpt.Dispose()
    oRpt = Nothing
-----------------------

optReportのクラスをoRptと同じようにCloseすることを試みましたが、
コマンドが存在しないためやむなくNothingを代入しております。

以上のソースの部分を外出ししてメソッド化して呼び出しを行ったり、別のクラスにして呼び出しを行ったりしましたが
現象の改善にはいたりませんでした。

引き続き何かございましたらご教授いただけたらと思います。

引用返信 編集キー/
■54022 / inTopicNo.5)  Re[4]: 帳票出力時、メモリエラーが発生
□投稿者/ もりお (288回)-(2010/10/02(Sat) 18:54:12)
No54018 (セプト さん) に返信

メモリーが逼迫しているということなのですかね。
Using 句を使用して、変数 dtlOutputPage のスコープを狭めてもダメですか?

Using oRpt As New cryBlockCa()
  Dim optReport As New CrystalDecisions.Shared.DiskFileDestinationOptions()
  Dim dtlOutputPage As DataTable = ...
  oRpt.SetDataSource(dtlOutputPage)
  'レポート出力先
  optReport.DiskFileName = strFilePath
  'レポートの出力形式を決定
  oRpt.ExportOptions.DestinationOptions = optReport
  oRpt.ExportOptions.ExportDestinationType = CrystalDecisions.Shared.ExportDestinationType.DiskFile
  oRpt.ExportOptions.ExportFormatType = CrystalDecisions.Shared.ExportFormatType.PortableDocFormat
  oRpt.Export()   'レポート出力
  oRpt.Close()
End Using

引用返信 編集キー/
■54024 / inTopicNo.6)  Re[5]: 帳票出力時、メモリエラーが発生
□投稿者/ セプト (4回)-(2010/10/02(Sat) 20:32:42)
No54022 (もりお さん) に返信
もりおさん返信ありがとうございます。

>Using 句を使用して、変数 dtlOutputPage のスコープを狭めてもダメですか?

もりおさんのご指摘通り試してみましたが、改善は見られませんでした。
さらにこちらで以下のような極端なことを試してみました。

Dim oRpt As New cryBlockCa()
---------------------------------
コメントアウト
---------------------------------
oRpt.Close()

これでもメモリエラーが発生いたします。
このあと、Dim oRpt As New cryBlockCa()とoRpt.Close()をコメントアウトするとエラーは発生しないことを確認しました。

引き続き何かございましたらご教授いただけたらと思います。

引用返信 編集キー/
■54026 / inTopicNo.7)  Re[6]: 帳票出力時、メモリエラーが発生
□投稿者/ もりお (289回)-(2010/10/02(Sat) 21:37:16)
No54024 (セプト さん) に返信

> これでもメモリエラーが発生いたします。
> このあと、Dim oRpt As New cryBlockCa()とoRpt.Close()をコメントアウトするとエラーは発生しないことを確認しました。

そうすると cryBlockCa のコンストラクタで重たい処理が行われるか。
もしくは、PDF ファイルの結合処理の負荷が高すぎるのではないでしょうか。

cryBlockCa が Crystal Report によって自動生成されたものとして。
PDF ファイルの結合処理は iText で行っているのでしょうか。
その部分のコードをお教えいただくことはできますか?

引用返信 編集キー/
■54034 / inTopicNo.8)  Re[7]: 帳票出力時、メモリエラーが発生
□投稿者/ セプト (5回)-(2010/10/03(Sun) 12:21:38)
No54026 (もりお さん) に返信
返信ありがとうございます。
もりおさんのご要望通りPDF結合部分のコードを公表します。

PDFの結合部分は別のClassで処理を行っております。
「Private Class ClsUnionPdf」がPDF結合部分のClass
「Public Function UnionPdf」が最上位のメソッド
「PdfOutPut」が実際にPDFを結合している部分になります。
---------------------------------
    Private Class ClsUnionPdf
        ' 戻り値:結合したPDFファイルのファイルサイズ(結合しない場合は0)
        Public Function UnionPdf(ByVal strProcessCode As String, ByVal strMode As String, ByVal strOutputFilePath As String) As String
            Dim TempDirectoryControl As DirectoryControl
            Dim DeleteFileControl As FileControl
            Dim strViewFile As String()
            Dim strInputPath(38) As String
            Dim pdfFormat As PdfReader
            Dim dc As Document
            Dim fs1 As FileStream
            Dim wr1 As PdfWriter
            Dim pcb As PdfContentByte
            Dim common As New Common

            Dim FormatPageSize As Rectangle
            Dim FormatWidth As Single
            Dim FormatHeight As Single

            Dim fi As System.IO.FileInfo

            Dim strSampleFileNames As String()
            Dim lngPageNo As Long
            Dim fntFooter As Font

            Dim strDeleteFilePath(9) As String
            Dim OpenFileOrDirCheck As New OpenFileOrDirCheck
            Dim intForCnt As Integer

            'ファイルの読み込みパターンの決定
            frmMainG0401_03.CasePattern(strProcessCode, strInputPath, strMode)

            TempDirectoryControl = New DirectoryControl(frmMainG0401_03.strTempFilePath)
            If TempDirectoryControl.GetSameNameFileAmount(frmMainG0401_03.strTempFileName) > 0 Then
                TempDirectoryControl.DeleteFileFromDirectory(frmMainG0401_03.strTempFileName)
            End If
            TempDirectoryControl = Nothing

            ' フッターのフォント
            fntFooter = New Font(com.lowagie.text.Font.BOLD, 10)
            strSampleFileNames = System.IO.Directory.GetFiles(System.AppDomain.CurrentDomain.BaseDirectory() & "\ShipData\" & My.Settings.cfgSHIP_DATA & "\00_index")

            pdfFormat = New PdfReader(strSampleFileNames(0))
            ' 出力用PDFオブジェクトの生成
            dc = New Document(pdfFormat.getPageSizeWithRotation(1))

            ' 出力用PDFファイルのオープン
            fs1 = New FileStream(frmMainG0401_03.strTempFilePath & "\" & frmMainG0401_03.strTempFileName, FileMode.Create, FileAccess.Write, FileShare.Write)

            ' 出力用PDFオブジェクトとPDFファイルの関連付け
            wr1 = PdfWriter.getInstance(dc, fs1)

            ' PDF出力開始
            dc.open()

            ' PdfContentByte取得
            pcb = wr1.getDirectContent()

            FormatPageSize = pdfFormat.getPageSize(1)
            FormatWidth = FormatPageSize.width()
            FormatHeight = FormatPageSize.height()
            strViewFile = Nothing

            'PDF出力部分(全フォルダを抽出)
            For intForCnt = 0 To strInputPath.Length - 1

                frmMainG0401_03.PdfOutPut(intForCnt, lngPageNo, strInputPath, strViewFile, FormatWidth, FormatHeight, fntFooter, dc, wr1, pcb)

            Next

            ' PDF出力終了
            dc.close()

            fs1.Close()
            fs1.Dispose()
            pdfFormat.close()

            DeleteFileControl = New FileControl(strOutputFilePath)
            If DeleteFileControl.IsFileExist = True Then
                DeleteFileControl.DeleteFile()
            End If
            DeleteFileControl = Nothing

            System.IO.File.Copy(frmMainG0401_03.strTempFilePath & "\" & frmMainG0401_03.strTempFileName, strOutputFilePath)

            'ファイルのサイズを取得
            fi = New System.IO.FileInfo(strOutputFilePath)

            UnionPdf2 = fi.Length

        End Function

    End Class
=================================
    Public Sub PdfOutPut(ByVal j As Integer, _
                         ByRef lngPageNo As Long, _
                         ByRef strInputPath() As String, _
                         ByRef strViewFile() As String, _
                         ByVal FormatWidth As Single, _
                         ByVal FormatHeight As Single, _
                         ByVal fntFooter As Font, _
                         ByRef dc As Document, _
                         ByVal wr1 As PdfWriter, _
                         ByRef pcb As PdfContentByte)

        Dim common As New Common
        Dim NewWidthSize As Single
        Dim NewHeightSize As Single


        Dim rd As PdfReader
        Dim blnPdfOverSize

        Dim PageSize As Rectangle
        Dim Width As Single
        Dim Height As Single

        Dim pn As Integer
        Dim pip As PdfImportedPage

        If j <= 27 Or j > 34 Then
            lngPageNo = 0
        End If

        ' 対象のディレクトリ直下にある、ファイル名に「.」を含むすべてのファイルのパスを配列で取得。
        strViewFile = System.IO.Directory.GetFiles(System.AppDomain.CurrentDomain.BaseDirectory() & "\ShipData\" & My.Settings.cfgSHIP_DATA & "\" & strInputPath(j), "*.pdf", IO.SearchOption.TopDirectoryOnly)

        ' 入力用PDFファイル毎の処理
        For p = 0 To strViewFile.Length - 1

            If strInputPath(j) = "" Then
                Exit For
            End If

            ' 入力用PDFファイルのオープン
            rd = New PdfReader(strViewFile(p))
            blnPdfOverSize = False

            'ページの用紙サイズを取得する
            PageSize = rd.getPageSize(1)
            Width = PageSize.width()
            Height = PageSize.height()
            NewWidthSize = 1
            NewHeightSize = 1
            If Width > FormatWidth Then
                NewWidthSize = (Math.Floor(FormatWidth / Width * 100) / 100)
                blnPdfOverSize = True
            End If

            If Height > FormatHeight Then
                NewHeightSize = (Math.Floor(FormatHeight / Height * 100) / 100)
                blnPdfOverSize = True
            End If

            ' 入力用PDFファイルのページ数取得
            pn = rd.getNumberOfPages()

            ' PDF出力処理
            For i As Integer = 1 To pn

                'フッター 埋込処理
                SetFooter(j, lngPageNo, fntFooter, dc, i)

                ' 改ページ
                dc.newPage()
                ' ページ取得
                pip = wr1.getImportedPage(rd, i)

                ' ページ出力
                If j = 0 Or j = 1 Or j = 2 Or j = 4 Or j = 6 Or j = 8 Or j = 10 Or j = 12 Or j = 14 Or j = 16 Or j >= 20 Then
                    pcb.addTemplate(pip, 1, 0, 0, 1, 0, 0)
                Else
                    If blnPdfOverSize = True Then
                        If NewHeightSize >= NewWidthSize Then
                            pcb.addTemplate(pip, NewWidthSize - 0.1, 0, 0, NewWidthSize - 0.1, 0, 50)
                        Else
                            pcb.addTemplate(pip, NewHeightSize - 0.1, 0, 0, NewHeightSize - 0.1, 0, 50)
                        End If
                    Else
                        pcb.addTemplate(pip, 0.9F, 0, 0, 0.9F, 0, 50)
                    End If
                End If

            Next
            rd.close()
            rd = Nothing
        Next

    End Sub
---------------------------------
何かお気づきの点がございましたら、ご教授ください。

引用返信 編集キー/
■54067 / inTopicNo.9)  Re[8]: 帳票出力時、メモリエラーが発生
□投稿者/ もりお (290回)-(2010/10/04(Mon) 14:41:19)
No54034 (セプト さん) に返信

ご掲示いただいたコードを拝見する限り、急速にメモリーを消費するようなところ
は、無いような気がします。
OutOfMemoryException の例外は結合処理のどの行で投げられますか?

こんな感じに結合処理を最小限にしても発生しますか?

Sub mergePdf(ByVal outputFilePath As String, ByVal inputFilePaths() As String)
  Dim document As New Document()
  Using os As New FileStream(outputFilePath, FileMode.Create)
    Try
      Dim writer As PdfWriter = PdfWriter.getInstance(document, os)
      document.Open()
      Dim content As PdfContentByte = writer.DirectContent
      For Each inputFilePath As String In inputFilePaths
        Dim reader As PdfReader = New PdfReader(inputFilePath)
        Try
          For pageNumber As Integer = 1 To reader.getNumberOfPages()
            document.newPage()
            content.addTemplate(writer.getImportedPage(reader, pageNumber), 1.0F, 0, 0, 1.0F, 0, 0)
          Next
        Finally
          If reader IsNot Nothing Then reader.Close()
        End Try
      Next
    Finally
      If document IsNot Nothing Then document.close()
    End Try
  End Using
End Sub

引用返信 編集キー/
■54092 / inTopicNo.10)  Re[9]: 帳票出力時、メモリエラーが発生
□投稿者/ セプト (6回)-(2010/10/05(Tue) 02:03:14)
2010/10/05(Tue) 02:16:16 編集(投稿者)
2010/10/05(Tue) 02:16:09 編集(投稿者)

No54067 (もりお さん) に返信
返信ありがとうございます。
質問にお答えいたします。

メモリエラーですが、どの行で発生するかはつかめておりません。
というのも、メモリエラーは一瞬にして発生するのではなく、徐々にあがっていき限界値に達した所で発生しております。

そのため、10件、100件程度の件数では発生しないこともあります。
今回は仕様上常時2000件程度の帳票を出力するシステムであるのと、
2000件で必ずメモリエラーが発生するため今回の対象件数を2000件といたしました。

データからPDFファイルを出力せずに、PDFファイルを2000件結合するだけですとメモリエラーは発生いたしません。

もりおさんに修正していただいたソースの修正の件ですが、
拝見した所「Private Class ClsUnionPdf」PDF結合部分のClassを全て置き換えて「mergePdf」に修正し、
テストすると認識しておりますがよろしいでしょうか?

あまりにもソースの量が違うので、念のため確認させていただきたいと思います。

現在こちらでソースの見直しも同時にやっておりましたが、ソースまで直していただけるとは感謝しております。
また、ここまで結合処理を最小限にできることに驚いております。
引用返信 編集キー/
■54093 / inTopicNo.11)  Re[10]: 帳票出力時、メモリエラーが発生
□投稿者/ もりお (291回)-(2010/10/05(Tue) 06:04:50)
No54092 (セプト さん) に返信

> 現在こちらでソースの見直しも同時にやっておりましたが、ソースまで直していた
> だけるとは感謝しております。
> また、ここまで結合処理を最小限にできることに驚いております。

私のコードは修正を目的としたものではありません。メモリーを消費する場所を明確
にすることを意図したコードです。
結合処理のみを行って、OutOfMemoryException が投げられるようなら、Footer 出力
部分などは原因から除外できるかと思った次第です。
誤解を与えてしまいました。すみません。

iText.NET 2005 1.4.6-2 を用いて
物理メモリ 3GB な環境で 2MB の PDF ファイルを 2000 個結合してみました。

PDF ファイルを読み込むごとに、ゆるゆると、物理メモリの使用率が上昇して、
1500 個読み込んだところで、
Dim reader As PdfReader = New PdfReader(inputFilePath)
この部分で、OutOfMemoryException が発生しました。

結合処理におけるメモリー消費は無視できないもののようです。
うーむ、コーディングで軽減できるかは、わかりません。

引用返信 編集キー/
■54128 / inTopicNo.12)  Re[11]: 帳票出力時、メモリエラーが発生
□投稿者/ もりお (293回)-(2010/10/06(Wed) 00:10:03)
2010/10/06(Wed) 06:02:11 編集(投稿者)
PDF ファイル結合処理におけるメモリー消費に関しての、補足です。
No54067 の処理をさらに分割して試行してみたところ、次のメソッドの呼び出しでメモリーを消費
することがわかりました。

writer.getImportedPage(reader, pageNumber)

iText.NET のソースコードを眺めてみると。
PdfWriter.getImportedPage メソッドを呼び出すことによって、PdfReader のインスタンスを
PdfWriter 内部のハッシュテーブルに保持し。
PdfWriter.close メソッドを呼び出すことによって、内部のハッシュテーブルに保持した
PdfReader のインスタンスを列挙し、PDF ファイルを読み込み、出力ストリームに書き込む。
というようになっています。

PdfReader のインスタンスは、PdfWriter.getImportedPage メソッドを呼び出してから、
PdfWriter.close メソッドを呼び出すまでの間、PdfWriter の内部にて保持されます。
これが、PDF ファイル結合処理においてメモリーを消費することの原因のようです。

iText の API を眺めてみると。PdfWriter クラスに freeReader メソッドというものが
あるようです。メモリーの消費を抑えたい場合には、このメソッドを適当なタイミングで呼び出すと
よいのではないかと思います。

API documentation 
http://api.itextpdf.com/com/itextpdf/text/pdf/PdfWriter.html#freeReader(com.itextpdf.text.pdf.PdfReader)

引用返信 編集キー/
■54157 / inTopicNo.13)  Re[12]: 帳票出力時、メモリエラーが発生
□投稿者/ セプト (7回)-(2010/10/07(Thu) 01:48:08)
No54128 (もりお さん) に返信
返信遅れてすみません。セプトです。
メモリ消費の原因とアドバイスをしていただき誠にありがとうございます。

こちらでいただいたソースで動作確認を行った結果、確かに現象が発生することを確認しました。
しかし、アドバイスいただいた「PdfWriter クラスの freeReader メソッド」を使用して以下のようにやってみましたが、
メモリの消費を押さえることはできませんでした。

Sub mergePdf(ByVal outputFilePath As String, ByVal inputFilePaths() As String)
  Dim document As New Document()
  Using os As New FileStream(outputFilePath, FileMode.Create)
    Try
      Dim writer As PdfWriter = PdfWriter.getInstance(document, os)
      document.Open()
      Dim content As PdfContentByte = writer.DirectContent
      For Each inputFilePath As String In inputFilePaths
        Dim reader As PdfReader = New PdfReader(inputFilePath)
        Try
          For pageNumber As Integer = 1 To reader.getNumberOfPages()
            document.newPage()
            content.addTemplate(writer.getImportedPage(reader, pageNumber), 1.0F, 0, 0, 1.0F, 0, 0)

      writer.freeReader(reader)←ここに配置

          Next
        Finally
          If reader IsNot Nothing Then reader.Close()
        End Try
      Next
    Finally
      If document IsNot Nothing Then document.close()
    End Try
  End Using
End Sub

しかし、もりおさんのおかげで、ソース上での不備でなくiText.NETの仕様上の動きで起こる現象とわかりましたので、
GCを使用しメモリの解放を試みました。

その結果以下の3行をwriter.freeReader(reader)の場所に配置することで、メモリの消費を押さえることに成功しました。

            GC.Collect()
            GC.WaitForPendingFinalizers()
            GC.Collect()

これにより2000枚のPDFファイルの出力が可能になりましたので、問題の解決となりましたことを報告いたします。
質問に答えてくださった皆様、本当にありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -