- ベストアンサー
WebアプリでのPDF出力
WebアプリでのPDF出力するプログラムがあり、メモリを多く消費するということで 改修の検討がされています。よくわからないのですがPDFを出力するにあたって メモリを節約するような出力の手法はあるのでしょうか。 PDFの作成自体は外部のプログラムで行っており、InputStreamを取得して ByteBuffer??とか~bufferなどというたぐいのクラスを使用して OutputStreamに書き出しています(処理内容がうろ覚えのあやふやですみません)。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>他に考えられる原因はなにかありますでしょうか。 visualvmを使用されてるのでしたらヒープダンプで、何のオブジェクトがメモリを使用しているのか確認はされました?
その他の回答 (5)
- wormhole
- ベストアンサー率28% (1626/5665)
>それともInputStreamを読み込むループの中で読み込んだ内容をbyte配列化してOutputStreamに書き込んでいけばよいのでしょうか。 「読み込んだ内容をbyte配列化」というのはわかりませんが(byte配列に読み込むんだから「読み込んだ内容をbyte配列化」とはいわないと思うし) // InputStream in // OutputStream out byte[] b = new byte[4096]; int len; while ((len = in.read(b)) > 0) { out.write(b, 0, len); } のように少しづつ読み込み、それを出力すればよいのでは? と書いてるんですけど。
補足
ご回答ありがとうございます。 教えていただきましたようにbyte配列に少しずつ 読み込む形式で修正を行いました。 しかし、PDF作成ボタン押下後のメモリの使用量を jdk付属のvisualVmで監視したところ ヒープの使用量(150Mぐらい)がほとんど改善されませんでした。 PDF作成に五分くらいかかるのですがその間にじわじわと メモリ使用量が上昇していく感じです。 Java側の処理はInputStreamをbyte配列に読み込んだ内容 をoutputStreamに書き込む処理しか行っていないのですが 他に考えられる原因はなにかありますでしょうか。 Tomcatがメモリ使ってる???? 修正前のプログラムはInputStream(PDFファイルデータ)を byte配列に一気に読み込んでいたのでこれがヒープの使用量を 押し上げる原因と考えていました。 ただ、200ページ以上あるPDFファイルをbyte配列に読み込んで いるにもかかわらずそのサイズ(length)を見ると1.5Mほどで 実際に生成されるPDFファイルのサイズとほぼ一致して おりました。PDFファイルってこんなに軽量?なんでしょうか。
- Tacosan
- ベストアンサー率23% (3656/15482)
どのような動作を期待しているのかがさっぱり見えないのは, 私だけなのかなぁ.... そもそも「Java を経由しなきゃならん必然性」がまったくわからん.
- wormhole
- ベストアンサー率28% (1626/5665)
>InputStreamを直接OutputStreamに書き込むことはできるのでしょうか。 OutputStreamの仕様を調べればわかりませんか? >InputStreamを一旦ファイルに保存(サーバーに保存)してそれをOutputStreamに出力できないかと思うのですが可能でしょうか。 可能か不可能かでいえば可能ですけど。 その発想ですと結局ファイルとして保存したものをOutputStreamで出力するために再度InputStreamでbyte[]に全て読み込もうとされるのではないですか? 一度に全て読み込まずに少しずつ読み込み出力すればいいだけな気がしますけど。
補足
>OutputStreamの仕様を調べればわかりませんか OutputStreamについてJavaDocを見てみると 書き込み用のwrite()というのが用意されているのは わかるのですがその引数が byte[] となっており 一度ファイルをbyte配列に変換してから書き込む必要が あるのかと思いました。 それともInputStreamを読み込むループの中で読み込んだ 内容をbyte配列化してOutputStreamに書き込んでいけば よいのでしょうか。
- wormhole
- ベストアンサー率28% (1626/5665)
もしかしてですが 外部プログラムで作成したPDFファイルをInputStreamを使ってByteBufferなどに全て読み込んだ後にOutputStreamで出力してるのではないですか?
補足
ご指摘の通りです。InputStreamをbyte[]で取得してます。 そこでなのですが InputStreamを直接OutputStreamに書き込むことはできるのでしょうか。 できないのであれば InputStreamを一旦ファイルに保存(サーバーに保存)してそれを OutputStreamに出力できないかと思うのですが可能でしょうか。
- LancerVII
- ベストアンサー率51% (1060/2054)
こんにちは。 外部のアプリとは、まったく別のシステムでしょうか? 生成されたファイルを取ってくるだけではそんなメモリを使うとは思いません。 PDF自体は何で生成していますか?
補足
外部アプリとは別の言語(確かCで作成)で作成したモジュール です。PDFファイル(100ページ以上)をInputStreamで 受け取ってbyte配列に読み込んでいるためメモリを使用して いると思われます。
補足
すみません。ヒープダンプのボタンに気が付いてませんでした。 早速、試してみます。 ありがとうございます。