« 2007年11月21日 | メイン | 2007年11月23日 »
2007年11月22日
XSL Formatter Java Interface について
先日、XSL FormatterのJavaインターフェイスについて問題が報告されていて、調査したところ、Javaインターフェイス自体には特に問題がなかったということをお話しました。
2007年11月19日 バグほど高いものはない。バグ一匹20万円也
調査結果には、Javaインターフェイスを使う人にとって参考になるところがあると思いますので、ここに少し紹介しておきます。
まず、最初に仕組みを簡単に説明しますと、JavaインターフェイスはJavaVMの上で動きます。一方、FormatterはC++のプログラムですので、JavaVMとは別のメモリ空間で動作します。Javaインターフェイスの方ではXSLTを動作させて、XMLをXSL-FOに変換します。この処理はJavaVM上で行われます。XSL-FOをFormatter側に受け渡して、FormatterがXSL-FOからPDFに変換します。
XSL-FOの受け渡しは、弊社のサンプルプログラムでは、バイトの配列としてメモリ上に展開したものを受け渡します。
このJavaインターフェイスを使ってFomatterを、Webアプリケーション・サーバ(Tomcat)で動かしているとメモリがなくなった(OutOfMemory)というエラーになって、Tomcatが動かなくなってしまうという問題です。
JavaVM上のメモリの余地がなくなってしまうという現象が起きているのですが、システムとしては、Fomatterで組版している最中にFormatterが動かなくなったように見え、Formatterの問題として報告されます。
解決策は、JavaVMのメモリを調整すること、FOをメモリに展開しないで、テンポラリのファイルに吐き出すようにすることなどがあります。
こういうことは、最初のうちはなかなか分からず、いろいろ試行錯誤してみて解決した後で、そうだったのか、ということが分かることが多いと思います。そういう意味ではシステムを作った経験の蓄積が多いと、問題の解決も早くなるだろうと思います。
ベンダーとしては、こういうノウハウ的な情報をもっと集めて公開することが必要と思います。
ところで、JavaVMの上でメモリがどのように使われているかの調査結果がありますので、公開しておきます。
1.XMLをXSL-FOに展開するXSLTプロセサのメモリ使用量
XSLTプロセサ:Xalan
FOファイルを作成した際のJavaのガベージコレクション(GC)の状況をグラフ化したもの。
1度の変換処理に約10MBのメモリを使用しています。
XMLファイル:約3.42MB
FOファイル:約4.81MB
上の図で、階段の1段が1回のXSLT変換に相当します。2回のXSLT変換に1回の割合でJAVAのフルGCが行われています。
2.FOからPDFへ(但し、JavaVM上のみ)
1スレッドから連続して、PDFファイルを生成した際のGCの状況です。
1度の生成処理に約1.5MBのメモリを使用しています。
FOファイル:約4.81MB
PDFファイル:約2.55MB
上の図で、階段の1段が1回のFOからPDF変換に相当します。こちらの方は、20回に1回程度の割合でJavaのフルGCが行われます。
FOからPDFへの変換の大部分は、C++のプログラムになりますので、処理の実体は、JavaVMの外部で行われていることになります。
こうした図をみますと、XMLをFOに変換する処理にかなり大量のメモリが使われているということがわかります。また、JavaのフルGCは1回の処理毎ではなく、何回かの処理毎に行われますので、一時的にですが、かなり大量のメモリを必要とする瞬間があるということがわかります。
投票をお願いいたします