setContextClassLoader 的含义

发布于 2024-10-20 16:33:39 字数 965 浏览 3 评论 0原文

与此问题类似:setContextClassLoader 影响,我正在尝试清除有关内存泄漏的警告。具体来说,我有一个代码如下的 servlet:

public void doGet(HttpServletRequest httpRequest, 
        HttpServletResponse httpResponse) throws ServletException, IOException {
    class BasicThread extends Thread {
        public void run() {
            // Do a finite amount of stuff here
        }
    }
    Thread thread = new BasicThread();
    //thread.setContextClassLoader(null);
    thread.start();
}

本文:http://wiki.apache。 org/tomcat/MemoryLeakProtection#cclThreadSpawnedByWebApp,表示如果我取消注释 setContextClassLoader 行,则错误消息将消失。

但我的问题是:是否存在内存泄漏?如果是这样,我不想只是让警告消失,我想修复泄漏。我该怎么做?

谢谢。

(另外,如果我将“//在这里做有限数量的事情”更改为“//在这里做无限数量的事情(即永远循环)”,那么正确的是什么确保在这种情况下没有内存泄漏的方法?)

Similar to this question: setContextClassLoader implications, I am trying to clean up warnings about memory leaks. Specifically, I have a servlet with code as follows:

public void doGet(HttpServletRequest httpRequest, 
        HttpServletResponse httpResponse) throws ServletException, IOException {
    class BasicThread extends Thread {
        public void run() {
            // Do a finite amount of stuff here
        }
    }
    Thread thread = new BasicThread();
    //thread.setContextClassLoader(null);
    thread.start();
}

This article: http://wiki.apache.org/tomcat/MemoryLeakProtection#cclThreadSpawnedByWebApp, indicates that if I uncomment the setContextClassLoader line, then the error messages will go away.

But my question is: is there a memory leak? If so, I don't want to just make the warnings go away, I want to fix the leak. How do I do so?

Thanks.

(also, if I change the line "// Do a finite amount of stuff here" to "// Do an infinite amount of stuff here (ie, loop forever)", then what is the proper way of ensuring no memory leaks in this scenario?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苍白女子 2024-10-27 16:33:39

仅当以下情况为真时,这才是真正的问题。 1. 线程永远不会停止,如果线程永远不会停止,那么就没有GC根,并且ClassLoader永远不会被垃圾收集。 2.您的应用程序正在进行热部署,那么您一定要考虑到这一点。

根本问题是,当您想要取消部署和重新部署时,应用程序服务器将需要 GC WAR 的类加载器。如果 WAR 创建了一个强烈引用 WAR 类加载器的线程,并且该线程尚未完成,则类加载器永远无法进行垃圾收集,最终您将看到内存不足:Permagen。

如果您为每个部署重新启动服务器(和 JVM),则问题不会显现出来。

我通读了您发布的文章,它们准确地描述了我的建议

严重:网络应用程序似乎
已经启动了一个名为
[leakingThread] 但未能停止
它。这极有可能创造一个
内存泄漏。

为了获得更多参考点,我提出了一个关于类加载器泄漏的类似问题

This is only a real issue if the following are true. 1. The thread never stops, if the thread never stops there is no GC root and the ClassLoader can never be garbage collected. 2. Your application is doing hot deployments then you should definitely take this into account.

The underlying issue is, when you want to un-deploy and re-deploy, the application server will want to GC the WAR's classloader. If the WAR has created a Thread strongly referencing the WAR's classloader and the Thread has not completed the classlodaer can never get garbage collected and eventually you will see a Out of memory: Permagen.

If you restart your server (and JVM) for each deployment the issue wouldn't manifest.

I read through the article you posted and they describe exactly what I suggested

SEVERE: A web application appears to
have started a thread named
[leakingThread] but has failed to stop
it. This is very likely to create a
memory leak.

For more of a point of reference, I asked a similar question regarding classloader leaks.

蓬勃野心 2024-10-27 16:33:39

请注意,一般来说,这是一个糟糕的设计。我可以通过执行一堆 get 调用轻松地使您的网络服务器崩溃(直到您有如此多的正在运行的线程以至于应用程序崩溃)。在这种情况下,您应该始终使用线程池。

如果您将其设置为使用线程池,并且根据 Web 应用程序的生命周期管理线程池,那么您应该不会有任何问题(例如,当 Web 应用程序重新(取消)部署时,相关的线程池应该得到关闭)。

另一方面(忽略线程过多的问题),如果您希望线程的生存期超过 Web 应用程序的生命周期,那么您应该清除上下文类加载器,因为大概这个线程无论如何都与有问题的 Web 应用程序并不真正相关(因为它有不同的生命周期)。

最后,直接回答你的问题之一,清除上下文类加载器的含义是,正在运行的线程可能无法访问为启动它的 web 应用程序部署的所有类。

Note, in general, this is a bad design. I could easily make your webserver fall over by executing a bunch of get calls (until you have so many running threads that the app falls over). you should always be using a thread pool in a situation like this.

if you set this up to use a thread pool, and you manage the threadpool based on the lifecycle of the webapp, then you shouldn't have any issues (e.g. when the webapp gets re(un)deployed, the relevant thread pool should get shutdown).

on the other hand (ignoring issues with too many threads), if you want the thread to live beyond the lifetime of the webapp, then you should clear out the context classloader, because presumably this thread is not really related to the webapp in question anyway (since it has a different lifecycle).

finally, to answer one of your questions dsirectly, the implication of clearing out the context classloader is that the running thread may not have access to all the classes which are deployed for the webapp which launched it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文