You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已解决Abandoned连接清理线程泄漏,求助Mojarra线程内存泄漏问题

解决Mojarra-WebResourceMonitor线程未停止导致的内存泄漏问题

我看你已经搞定了「Abandoned connection cleanup thread」的线程泄漏问题,但现在卡在了Mojarra的WebResourceMonitor线程上——这个问题其实是Mojarra(JSF的官方实现)里的一个常见小坑,尤其是在Web应用重启或者停止的时候,这个监控线程没被正确销毁,进而引发内存泄漏。结合你给出的线程堆栈(sun.misc.Unsafe.park(Native Method)说明线程正处于等待状态,没被正常终止),给你几个实用的解决方案:

方案1:直接升级Mojarra版本

这个线程泄漏的问题在Mojarra的旧版本里是已知bug,比如2.2.x的部分版本、2.3.x的早期版本都存在这个问题。官方在后续的稳定版本里已经修复了线程销毁的逻辑,直接升级到最新的稳定版(比如2.3.14及以后,或是Jakarta Faces 3.x/4.x的对应版本),基本就能彻底解决这个问题,这也是最推荐的方案,毕竟升级还能顺便获得其他bug修复和性能提升。

方案2:手动写监听器终止线程(临时应急方案)

如果暂时没法升级版本,可以自己写一个ServletContextListener,在应用停止的时候主动找到这个线程并终止它:

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.lang.reflect.Field;
import java.util.Set;

public class MojarraThreadCleanupListener implements ServletContextListener {
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        try {
            // 反射获取WebResourceMonitor的活跃线程集合
            Class<?> monitorClass = Class.forName("com.sun.faces.application.resource.WebResourceMonitor");
            Field threadSetField = monitorClass.getDeclaredField("activeThreads");
            threadSetField.setAccessible(true);
            Set<Thread> activeThreads = (Set<Thread>) threadSetField.get(null);

            // 逐个中断线程并等待终止
            for (Thread thread : activeThreads) {
                thread.interrupt();
                try {
                    thread.join(1000); // 等待1秒让线程完成收尾
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 初始化阶段无需操作
    }
}

写完后,在web.xml里注册这个监听器:

<listener>
    <listener-class>com.yourpackage.MojarraThreadCleanupListener</listener-class>
</listener>

⚠️ 注意:这个方案依赖Mojarra的内部类和字段,不同版本可能有结构变化,后续升级Mojarra后记得移除这个监听器,避免出现兼容问题。

方案3:关闭不必要的资源监控

如果你的项目不需要Mojarra的资源监控功能,可以直接在web.xml里添加参数关闭它,从根源上避免这个线程被启动:

<context-param>
    <param-name>com.sun.faces.enableResourceMonitoring</param-name>
    <param-value>false</param-value>
</context-param>

关闭后,WebResourceMonitor就不会启动对应的监控线程,自然也就不会有泄漏问题了。

内容的提问来源于stack exchange,提问作者Newbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:22:26