简体   繁体   English

Servlet“已启动一个线程但未能阻止它” - Tomcat中的内存泄漏

[英]Servlet “has started a thread but failed to stop it” - memory leak in Tomcat

Apache Tomcat says many times: Apache Tomcat多次说:

The web application [/MyServlet] appears to have started a thread named [pool-61-thread-2] but has failed to stop it. Web应用程序[/ MyServlet]似乎已启动名为[pool-61-thread-2]的线程,但未能将其停止。 This is very likely to create a memory leak. 这很可能造成内存泄漏。

Is this dangerous? 这有危险吗? The servlet should be able to handle 10.000requests/day. servlet应该能够处理10.000个请求/天。 How to close the threads when they have finished? 完成后如何关闭线程?

class Worker {

        private final CountDownLatch startSignal;
        private final CountDownLatch doneSignal;
        private final int threadNumber;

        Worker(
                CountDownLatch startSignal,
                CountDownLatch doneSignal,
                int threadNumber
        ){

            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
            this.threadNumber = threadNumber;

        }

        public String[][] getSomeStrArrArr() {

            String[][] isRs = new String[8][20];
            String[][] inRs = new String[8][20];
            String[][] iwRs = new String[8][20];

            try {

                startSignal.await();

                if (threadNumber == 1) {
                    // get String[][] result for thread number 1
                    isRs = getIS(erg1, erg2, request);

                }

                if (threadNumber == 2) {
                    // get String[][] result for thread number 2
                    inRs = getIN(search_plz, request);
                }

                if (threadNumber == 3) {
                    // get String[][] result for thread number 3
                    iwRs = getIW(erg1, erg2, request);
                }

                doneSignal.countDown();

            } catch (InterruptedException ex) {

                System.out.println(
                        "Thread number "+threadNumber+" has been interrupted."
                );

            }
            if (threadNumber == 1) {
                return isRs;
            }
            if (threadNumber == 2) {
                return inRs;
            }
            if (threadNumber == 3) {
                return iwRs;
            }
            return null;
        }


        public Callable<String[][]> getSomeCallableStrArrArr(){
            return new Callable<String[][]>() {
                public String[][] call() throws Exception {
                    return getSomeStrArrArr();
                }
            };
        }

    }

    ExecutorService pool = Executors.newFixedThreadPool(3);
    Set<Future<String[][]>> set = new HashSet<Future<String[][]>>();
    CountDownLatch startSignal = new CountDownLatch(1);
    CountDownLatch doneSignal = new CountDownLatch(3);
    for (int i=1;i<=3;i++) {
        Worker worker = new Worker(startSignal,doneSignal,i);
        Callable<String[][]> callable =
                worker.getSomeCallableStrArrArr();
        Future<String[][]> future = pool.submit(callable);
        set.add(future);
    }
    startSignal.countDown();
    try {
        doneSignal.await();

Yes, it's a problem. 是的,这是一个问题。 If your code starts non-daemon threads then those threads will continue working until they exit their run method. 如果您的代码启动非守护程序线程,那么这些线程将继续工作,直到它们退出其run方法。 Even if everything else finishes, the old JVM will hang around while those threads continue on. 即使其他一切都完成了,旧的JVM也会在这些线程继续运行的时候徘徊。 If you start up a new instance then you can have a situation where the old threads are still working alongside the ones created by the new instance. 如果启动一个新实例,那么您可能会遇到旧线程仍在与新实例创建的线程一起工作的情况。

The tasks need to be designed so that they will be responsive to interruption (as opposed to eating the exception and going on, which is what your example shows). 需要设计任务,以便他们能够响应中断(而不是吃异常并继续进行,这就是你的例子所示)。 That means checking the interrupted flag on the current thread, and catching InterruptedException in a helpful way that allows the task to break its work off and also resets the interrupted flag if needed. 这意味着检查当前线程上的中断标志,并以有用的方式捕获InterruptedException,允许任务中断其工作,并在需要时重置中断的标志。 ExecutorService implementations have a shutdownNow method that will interrupt the current tasks. ExecutorService实现有一个shutdownNow方法,它将中断当前任务。

Here's an example of how to stop a thread using interruption . 这是一个如何使用中断停止线程的示例

Make sure the executor gets shut down, you can handle this in a ServletContextListener . 确保执行程序关闭, 您可以在ServletContextListener中处理它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Tomcat webapp错误-应用程序启动了线程[AWT-Windows],但未能将其停止-内存泄漏? - Tomcat webapp error - application started thread [AWT-Windows] but has failed to stop it - memory leak? 如何解决 tomcat 内存泄漏警告 - Web 应用程序已启动一个线程但未能将其停止 - How to resolve tomcat memory leak warning - The web application have started a thread but has failed to stop it 该Web应用程序似乎已启动一个名为的线程,但未能停止该线程。 这很可能造成内存泄漏 - The web application appears to have started a thread named but has failed to stop it. This is very likely to create a memory leak Web应用程序似乎已启动名为[22]的线程但未能阻止它。 这很可能造成内存泄漏 - A web application appears to have started a thread named [22] but has failed to stop it. This is very likely to create a memory leak 使用Oracle JDBC驱动程序12c的Tomcat 7上的内存泄漏 - oracle.jdbc.driver线程无法停止 - Memory leak on Tomcat 7 with Oracle JDBC drivers 12c - oracle.jdbc.driver thread failed to stop Quartz2.x:严重:Web应用程序[/ servlet]似乎已启动名为[Thread-4]的线程,但未能停止它 - Quartz2.x: GRAVE: The web application [/servlet] appears to have started a thread named [Thread-4] but has failed to stop it 战争servlet中的泄漏内存与tomcat - Leak memory in war servlet with tomcat tomcat7 servlet中的内存泄漏 - Memory leak in tomcat7 servlet tomcat关闭内存泄漏,java线程无法停止 - tomcat shutdown memory leak, java thread can not stop 服务器由于[Pool-Cleaner]:Tomcat连接池而停止响应,但未能停止它。 这很可能造成内存泄漏 - Server Stop responding because of [Pool-Cleaner]:Tomcat Connection Pool but has failed to stop it. This is very likely to create a memory leak
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM