tomcat线程释放时间_tomcat关闭应用时的清理工作(2): 线程的清理

本文探讨了Tomcat在关闭应用程序时遇到的线程未释放问题,可能导致内存泄漏的警告信息。内容包括WebappClassLoader的clearReferencesThreads方法如何检测并警告未终止的用户线程,以及如何通过设置unloadDelay属性限制请求处理时间。同时,通过实例展示了两种警告情况:一种是应用启动的线程未被终止,另一种是请求线程仍在处理。最后,提到了Tomcat默认不会强制停止这些线程,除非配置为true,且可能会使用已废弃的Thread.stop方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

tomcat在关闭时,有时会看到类似下面的警告信息:

2014-7-10 13:44:02 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

SEVERE: The web application [] appears to have started a thread named

[com.taobao.xxx.client.Timer] but has failed to stop it.

This is very likely to create a memory leak.

这是tomcat关闭应用时检测到了应用启动的线程未被终止,tomcat为防止造成内存泄露,给出上面的警告,并根据配置来决定是否强制停止该线程(默认不会强制停止)。

有时也会有另一种相似的警告信息:

2014-7-10 13:44:02 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

SEVERE: The web application [] is still processing a request that has yet to finish.

This is very likely to create a memory leak.

You can control the time allowed for requests to finish

by using the unloadDelay attribute of the standard Context implementation.

这是tomcat关闭应用时检测到了仍有请求线程未处理完。

上面的2种警告都是在WebappClassLoader的clearReferencesThreads方法里给出的,该方法也是在stop时调用clearReferences方法时调用的:

protected void clearReferences() {

...

// Stop any threads the web application started

clearReferencesThreads();

...

}

在clearReferencesThreads方法里,通过找到最顶层的root thread group获取所有的active线程,然后判断这些线程如果是用户线程的话,给出警告:

if (isRequestThread(thread)) {

log.error(sm.getString("webappClassLoader.warnRequestThread",

contextName, thread.getName()));

} else {

log.error(sm.getString("webappClassLoader.warnThread",

contextName, thread.getName()));

}

我们来模拟一下,先看第一种情况:

@WebServlet(name = "MainServlet", urlPatterns = { "/main" }, loadOnStartup = 1)

public class MainServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void init() {

new Thread() {

public void run() {

try {

while (true) {

Thread.sleep(1000);

}

} catch (Exception e) {

}

}

}.start();

}

}

在一个servlet初始化时启动了一个线程,没有提供销毁这个线程的机制,当tomcat停止时,会报第一种警告。

再模拟第二种警告情况,在请求时将线程hang住:

public void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

try {

Thread.sleep(1000 * 200);

} catch (Exception e) {

}

}

这时关闭tomcat时会报出第二种警告信息。

默认tomcat并不会强制将这些线程终止,除非设置了clearReferencesStopThreads为true,它判断线程属于某个线程池则延迟一段时间将线程终止,否则直接调用了JDK已不鼓励的Thread.stop方法终止线程。

if (usingExecutor) {

// Executor may take a short time to stop all the

// threads. Make a note of threads that should be

// stopped and check them at the end of the method.

executorThreadsToStop.add(thread);

} else {

// This method is deprecated and for good reason. This

// is very risky code but is the only option at this

// point. A *very* good reason for apps to do this

// clean-up themselves.

thread.stop();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值