ray*_*man 6 java performance multithreading jms jakarta-ee
我在独立环境中使用 Spring3.1。
(此问题与 Spring 无关。它在独立环境中的行为也相同。)
我已经实现了一个从主题接收消息的监听器。消息速率非常高(大约为 20/30 m/s)。
有些消息可能比其他消息需要更多的处理时间。
侦听器使用相同的实例,这意味着如果一条消息处理时间过长,它会严重影响我们的表现。
我们考虑过使用我们自己的对象池而不是使用相同的侦听器实例,但后来我发现了Executors (java.util.concurrent.Executors)。
因此,对于收到的每条消息,都会为其分配不同的线程。这将确保我们的侦听器实例可以自由地并行处理消息。
private ExecutorService threadPool = Executors.newFixedThreadPool(100);
@Override
public void onMessage(final Message msg)
{
Runnable t = new Runnable()
{
public void run()
{
onSessionMessage(msg);
log.trace("AbstractSessionBean, received messge");
}
};
threadPool.execute(t);
}
Run Code Online (Sandbox Code Playgroud)
这似乎解决了我们的性能问题。但是在使用 jconsole 监视应用程序之后,我们现在面临着巨大的内存泄漏。
堆内存使用量随时间显着增加。
所以我试着用 FixedThreadPool 大小数字“玩”一下。仍然有巨大的内存使用量:

知道我该如何解决这个问题吗?还有其他想法可以解决我的关键问题吗?


运行 heap dump 后,我有两个问题嫌疑人:

谢谢,雷。
我认为你没有内存泄漏的问题,至少我无法从你的 jconsole 图表中看到它。没有主要的GC收集。因此,似乎只有越来越多的对象分配给终身(老)一代。为了确保内存泄漏,您应该执行 GC,然后比较分配的内存。如果发现泄漏,您可以使用 jmap 或可视化工具(标准 JDK 工具)进行堆转储。之后可以使用MAT分析该堆转储。在进行堆转储之前,最好执行 GC 以减少堆转储文件的大小。
一些注意事项: