4

iText に問題があります。

大量の画像を含む PDF を作成しているため、Java ヒープ領域が非常に簡単に不足します。

Eclipse Memory Analyzer で dmp を分析しようとしたところ、すべてのイメージが約 10MB のヒープ スペースを使用していることがわかりました。しかし、HDには約350KBしかありません

ヒープを HD にフラッシュして作成を続行する機会はありますか?

他によくある漏れはありますか?

残念ながら、まだ有用なものは何も見つかりませんでした。

ヒープ

これは、1 つの画像のヒープがどのように見えるかです。

一般に、追加された要素はキャッシュに残っていると思います...どうすればそれらを取り出すことができますか?

このようなことは可能ですか?

それは私が当時使っていたコードです:

Document document = new Document();
PdfWriter writer = null;
        try {
            writer = PdfWriter.getInstance(document, new FileOutputStream(this.savePath));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }

document.open();

Paragraph pdfTitle = new Paragraph();
pdfTitle.add(new Phrase("Title"));

try {
    document.add(pdfTitle);
    document.add(Chunk.NEWLINE);

} catch (DocumentException e) {
    e.printStackTrace();
}

for(int x = 0; x < 10; x++){
    //chapter
    Paragraph chapterName = new Paragraph("Chapter "+x, FONT[1]);
    ChapterAutoNumber chapter = new ChapterAutoNumber(chapterName);

    try {
    document.add(chapterhapter);
    } catch (DocumentException e) {
        e.printStackTrace();
    }

    for(int y = 0; y < 10; y++){
        //sec
        Paragraph sectionName = new Paragraph("Section "+y, FONT[2]);

        Section section  = chapter.addSection(sectionName);

        for(int z = 0; z < 10; z++){
            //subSec
            Section subSection = null;

            Image image = null;
            try {
            image = Image.getInstance(path);
            } catch (BadElementException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            image.scalePercent(50);

            image.setCompressionLevel(9);
            Paragraph subDesc = new Paragraph("Desc "+z, FONT[3]);

            subSection = section.addSection(subDesc);

            picSection.add(image);

            try {
                document.add(subSection);
            } catch (DocumentException e) {
                e.printStackTrace();
            }

        }

    }

}

document.close();
4

4 に答える 4

2

私は iText の最初の開発者であり、あなたのコードがすべて間違っているため、あなたの質問に反対票を投じました。

たとえば、章オブジェクトを作成しますが、それをドキュメントに追加することはありません。代わりに、どこにも定義されていない picSection オブジェクトを追加しています。

ただし、私の主な批判は、LargeElement インターフェイスを実装する ChapterAutoNumber オブジェクトを使用していて、メモリの使用について不満があるという事実です。それは、毎日マヨネーズを 1 瓶食べているのに、どうしてこんなに太っているのだろうと考えているようなものです。

なぜ章/セクションを使用しているのですか? ブックマークがこれらのオブジェクトを選択する主な理由である場合、使用するメモリを減らしたい場合は、PdfOutline の使用に切り替える必要があります。章オブジェクトにオブジェクトを追加することで、膨大な量のオブジェクトを構築しているからです。これらのオブジェクトは、文書に章を追加した時点でのみ解放されます。ガベージ コレクターは Chapter オブジェクトに格納されているコンテンツを破棄できないため、その瞬間までガベージ コレクションを実行しても意味がありません。

Chapter クラスの使用に慣れている場合は、 setComplete() メソッドを見て、章の小さな部分を定期的にドキュメントに追加して、オブジェクトを少しずつ解放できるようにします。最初のアプローチ (Chapter クラスを使用しない) は、この 2 番目のアプローチよりもはるかに優れています。

このような質問が他にもあれば、iText から Chapter/Section クラスを削除することにするかもしれません。

于 2012-09-10T11:45:33.860 に答える
1

100kBイメージが大量のメモリを消費する理由は、おそらくディスク上で圧縮され、メモリ内で非圧縮(raw)されているためです。

Javaはガベージコレクションを行い、同時に使用しすぎてメモリが不足しない限り、これを処理できるはずです。

この質問は、使用済みメモリのクリーンアップになります。Javaヒープオーバーフロー、ガベージコレクションの強制

オブジェクトを再利用すると、メモリ使用量が軽減される場合があります。最後のPDF/Imageオブジェクトを再利用して、次のオブジェクトをロードできますか?新しいオブジェクトを作成する代わりに意味しますか?

于 2012-09-10T08:02:44.273 に答える
1

ここにいくつかの役立つ答えがあります: Javaヒープスペースがメモリ不足です

画像を PDF に追加した後、画像を null に設定してみてください。

于 2012-09-06T10:39:11.463 に答える
1

私の最初の推測は、ある種のストリーミング サポートについて iText ドキュメントを検索することです。作成中のPDF全体をメモリに保存しない方法はありますか? RTFM。

2 番目のオプションは、適切なハードウェアがある場合、アプリケーションのヒープ サイズを大きくすることです。

念のため、メモリ リークの可能性について言及しておく必要があります。あなたの場合はありそうにないように思えますが、必要な場合はPlumbrがあります:)

于 2012-09-07T06:36:50.253 に答える