to topto bottom

モバイルファースト時代のマルチデバイス対応を確実・簡単に

重要なお知らせ JAIを使用した際のメモリリークについて

更新(FAQ追加):2010/01/29
更新(FAQ追加):2010/02/04

平素より『x-Servlet』をご愛顧いただき誠にありがとうございます。

この度、x-Servletの画像変換機能の利用時に必要となる JAI の一部ライブラリを原因としたメモリリークが発生する現象を確認しました。

つきましては、以下にx-Servletを導入いただいているお客さまへ、現象の概要と対処方法についてお知らせさせていただきます。

概要

x-Servletの画像変換機能の利用に必要となる、JAI をインストールした際に、同時に Java ネイティブライブラリがインストールされますが、これらのライブラリを使用するとCヒープ領域のメモリリークが発生します。

これにより OS上で Java が使用するメモリが増え続け、スワップファイルを使い切った時点で"Out of swap space"エラーを出して JVM が停止します。

対象

x-Servletの全バージョン、および全エディションにおいて、 JAI 1.1.2 以降を JAI のインストーラーを用いてインストールしており、x-Servletの画像変換機能を使用している場合に、上記問題が発生することがあります。

※2010年2月5日出荷予定の『x-Servlet Version2.8.1』では対応済みとなっております。

対処方法

この問題を回避するため、ネイティブライブラリを使用せず、ピュアJava で画像変換を行うよう JVM のオプションを追加してください。

start.bat (Windows OS の場合)

@echo off
rem
rem set environment
rem
set JAVA_EXE=java
set JVM_OPTION=-Dcom.sun.media.jai.disableMediaLib=true -Xms256M -Xmx512M -server
set XPROXY_CLASSPATH=xproxy.jar;xproxy_image_223.jar
set XPROXY_CLASSPATH=%XPROXY_CLASSPATH%;jars/log4j-1.2.9.jar
set XPROXY_CLASSPATH=%XPROXY_CLASSPATH%;.

set XPROXY_EXE_CLASS=jp.co.flexfirm.xproxy.control.ServerMain

rem
rem execute
rem
@echo on

%JAVA_EXE% %JVM_OPTION% -classpath %XPROXY_CLASSPATH% %XPROXY_EXE_CLASS%

start.sh (Linux系 OS の場合)

#!/bin/sh

#
# set environment
#
SET_ENV="env LANG=ja_JP.eucJP"
JAVA_EXE="java"
JVM_OPTION="-Dcom.sun.media.jai.disableMediaLib=true -Xms256M -Xmx512M -server"
XPROXY_CLASSPATH="xproxy.jar:xproxy_image_223.jar"
XPROXY_CLASSPATH="$XPROXY_CLASSPATH:jars/log4j-1.2.9.jar"
XPROXY_CLASSPATH="$XPROXY_CLASSPATH:."

XPROXY_EXE_CLASS="jp.co.flexfirm.xproxy.control.ServerMain"

#
# write PID
#
PID_FILE=./xproxy.pid

if [ -f $PID_FILE ]
then
      echo "It has already started."
      exit 1;
else
      #
      # execute
      #
      $SET_ENV $JAVA_EXE $JVM_OPTION -classpath $XPROXY_CLASSPATH $XPROXY_EXE_CLASS &

      echo $! > $PID_FILE

      wait `cat $PID_FILE`
      rm -f $PID_FILE
fi

#
# EOF
#

上記設定をおこなっていただくことにより、メモリリークの問題を解消することができます。

JAI メモリリーク問題 FAQ

Q.ネイティブライブラリを使用しているか確認するには?
A.以下のライブラリファイルがシステム上に存在するかご確認ください。
  [Windows系]
  %JAVA_HOME%\jre\bin\mlib_jai.dll
  %JAVA_HOME%\jre\bin\mlib_jai_mmx.dll
  %JAVA_HOME%\jre\bin\mlib_jai_util.dll
  
  [Linux系]
  $JAVA_HOME/jre/lib/i386/libmlib_jai.so
  もしくは
  $JAVA_HOME/jre/lib/amd64/libmlib_jai.so
 
Q.メモリリークが発生しているか確認するには?
A.vmstat 等で java.exe が OS 上で消費しているメモリサイズを計測してください。
メモリリークが発生している場合はスワップファイルの使用量も増大します。
メモリリークの結果、JAVA がクラッシュした際にローカルディスクに
hs_err_pid****.log (****はJAVAのプロセスID) というファイルが出力され、下記のようなメッセージが記述されます。
    
  # java.lang.OutOfMemoryError: requested 20512 bytes for GrET in 
  C:\BUILD_AREA\jdk6_18 \hotspot\src\share\vm\utilities\growableArray.cpp. 
  Out of swap space?
          
   
Q.ピュアJava で画像変換を行うようにした場合、パフォーマンスにはどの程度影響あるか?
A.x-Servletでは高度な画像変換処理を行っていないのでピュアJavaでの画像変換でもネイティブライブラリを使用していた場合とほぼ同等のパフォーマンスとなります。
Q.ピュアJava で画像変換を行った場合、画像ファイルへの影響は?
A.画像変換ロジックに変更はないので出力されるファイルに違いはありません。
Q.x-Servlet の画像変換機能は使用していないが、JAI がインストールされている場合は対処は必要か?
A.x-Servlet の画像変換機能は使用していない場合は JAI がインストールされていても対処の必要はありません。
Q.その他、対処の必要が無いケースは?
A.x-Servlet を起動後、最初の画像変換リクエストを受け取った際にコンソールに下記のようなメッセージが表示されている場合はピュアJavaで動作しているためにメモリリークは発生しません。
      
  Error: Could not load mediaLib accelerator wrapper classes.
  Continuing in pure Java mode.
  Occurs in: com.sun.media.jai.mlib.MediaLibAccessor
  com.sun.media.jai.mlib.MediaLibLoadException
        
    
 
Q.対処方法がきちんと反映されているか確認するには?
A.x-Servlet を起動した際の logs/xInfo.log に以下の記述がある場合はオプションが反映されています。    
      
    <com.sun.media.jai.disableMediaLib>=<true>
             
     

その他、本件につきましてご不明な点など御座いましたら、『x-Servletサポートチーム』までお問い合わせください。

タグ: 
x-Servlet