Spring Boot集成测试WebSocket后遇OOM及线程未终止问题求助
Spring Boot WebSocket集成测试后OutOfMemoryError排查与解决思路
我的Spring Boot集成测试在WebSocket相关测试完成后总会触发OutOfMemoryError,目前只能通过增大build.gradle中的maxHeapSize临时缓解,但这显然不是根治办法。
本地运行测试时会收到如下警告:
2023-07-24 13:26:32.113 WARN 42956 --- [ main] o.a.c.loader.WebappClassLoaderBase : The web application [ROOT] appears to have started a thread named [clientInboundChannel-32] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.base@17.0.6/jdk.internal.misc.Unsafe.park(Native Method) java.base@17.0.6/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252) java.base@17.0.6/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672) java.base@17.0.6/java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:460) java.base@17.0.6/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1061) java.base@17.0.6/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122) java.base@17.0.6/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) java.base@17.0.6/java.lang.Thread.run(Thread.java:833)
我怀疑这个线程未停止的警告和OOM直接相关。测试中已经使用了自定义WebSocket测试工具类,并且在测试完成后调用了连接关闭逻辑——工具类负责创建WebSocket客户端连接、发送消息等操作,测试基类在@AfterEach方法中执行连接关闭。
解决方案思路
- 确认资源释放的完整性:检查WebSocket工具类的关闭逻辑,确保不仅关闭了客户端连接,还清理了底层线程池、通道资源。比如Spring的
WebSocketClient实现(如StandardWebSocketClient)是否调用了stop()方法,是否存在未关闭的Session实例残留。 - 排查线程泄漏根源:
- 使用
jstack、VisualVM等JVM工具,在测试运行前后对比线程数量,确认clientInboundChannel这类线程是否持续累积。 - 检查WebSocket配置中是否自定义了线程池,若有,需确保测试结束后调用
shutdownNow()并等待线程池终止,避免线程驻留内存。
- 使用
- 优化测试生命周期管理:
- 避免在每个测试方法中重复创建WebSocket客户端实例,可在
@BeforeAll中初始化客户端,@AfterAll统一销毁,减少资源重复创建的开销。 - 给测试类添加
@DirtiesContext注解,在测试完成后重置Spring上下文,避免上下文残留的WebSocket资源不断累积。
- 避免在每个测试方法中重复创建WebSocket客户端实例,可在
- 定位OOM具体原因:启动测试时添加JVM参数
-XX:+HeapDumpOnOutOfMemoryError,生成堆转储文件后用MAT或JProfiler分析,确认是线程对象占用内存,还是WebSocket消息、会话实例未被GC回收。 - 改用官方测试工具:尝试使用Spring官方的WebSocket测试工具(如
WebSocketStompClient配合TestWebSocketClient),这类工具内置了完善的资源清理逻辑,能避免手动管理资源的疏漏。
内容的提问来源于stack exchange,提问作者Jan Cizmar
相关产品推荐
相关产品推荐

