キューからメッセージを消費し、ステートレス EJB を呼び出していくつかのデータベース操作を実行する MDB があります。このようなもの:
public class TestMDB implements MessageListener
{
@EJB
private UpdateService updateSvc;
@Override
public void onMessage(Message message)
{
try
{
updateSvc.updateSystemStatuses();
}
catch(Exception e)
{
// log error
}
}
}
上記のコードで updateSystemStatuses() 呼び出しが RuntimeException をスローすると、メモリ リークが発生するようです。updateSystemStatuses() で RuntimeExceptions をスローするように誘導することでプロセスを高速化しました。これが発生すると、CPU 使用率とメモリ使用率が急上昇します (JVisualVM で見られるように)。OutOfMemoryErrors が発生し始めるまで続きます。
onMessage から RuntimeExceptions をスローするようにコードを変更すると、リソース リークは完全になくなるようです。
public class TestMDB implements MessageListener
{
@EJB
private UpdateService updateSvc;
@Override
public void onMessage(Message message)
{
try
{
updateSvc.updateSystemStatuses();
}
catch(RuntimeException e)
{
//log error
throw e;
}
catch(Exception e)
{
//log error
}
}
}
EJB メソッドから RuntimeException をスローするとトランザクションのロールバックが発生することは承知しており、これは私が見ていることと関係があると思いますが、それ以上に何が起こっているのかはわかりません。リソース リークは Glassfish のバグですか? MDB で例外を正しく処理していますか?
Eclipselink と Oracle 11G を使用して、Java 1.6.0_35 で Glassfish 3.1.2.2 を実行しています。