Glassfish MDB异常处理中的明显资源泄漏

Glassfish MDB异常处理中的明显资源泄漏,glassfish,ejb,message-driven-bean,Glassfish,Ejb,Message Driven Bean,我有一个MDB,它使用队列中的消息,然后调用无状态EJB来执行一些db操作。大概是这样的: public class TestMDB implements MessageListener { @EJB private UpdateService updateSvc; @Override public void onMessage(Message message) { try { updateSvc.updateSystemStatuses();

我有一个MDB,它使用队列中的消息,然后调用无状态EJB来执行一些db操作。大概是这样的:

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()抛出运行时异常来加速这个过程,当发生这种情况时,CPU使用率和内存使用率会出现峰值(正如在JVisualVM中观察到的),直到我开始摆脱内存错误

如果我修改代码将RuntimeExceptions从onMessage中抛出,那么资源泄漏似乎会完全消失:

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会导致事务回滚,我假设这与我看到的有关,但除此之外,我不清楚这里发生了什么。资源泄漏是玻璃鱼虫吗?我是否以正确的方式处理MDB中的异常


我正在Java 1.6.035上运行Glassfish 3.1.2.2,使用Eclipselink和Oracle 11G。

我认为您正面临一个“有毒消息”的情况。MDB获取队列中的消息并尝试处理它。由于处理失败(抛出异常),消息将被放回队列中。一次又一次的处理。这就是为什么你会看到中央处理器(CPU)出现问题的原因

使用Glassfish,您可以指定消息在被忽略(即,如果处理引发异常)之前可以处理多少次。您将在本博客上找到有用的信息: