当前位置: 首页 > 面试题库 >

Servlet“已启动线程但无法停止线程” – Tomcat中的内存泄漏

宋高寒
2023-03-14
问题内容

Apache Tomcat多次说:

Web应用程序[/ MyServlet]似乎已启动名为[pool-61-thread-2]的线程,但未能停止它。这很可能造成内存泄漏。

这很危险吗?该servlet应该每天能够处理10.000个请求。完成后如何关闭线程?

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();

问题答案:

是的,这是一个问题。如果您的代码启动非守护程序线程,则这些线程将继续工作,直到退出运行方法。即使其他一切都完成了,当这些线程继续运行时,旧的JVM仍会徘徊。如果启动新实例,则可能会出现旧线程仍在与新实例创建的线程同时工作的情况。

必须对任务进行设计,以使它们能够对中断做出响应(这与吃异常并进行下去相反,这是您的示例所显示的)。这意味着检查当前线程上的中断标志,并以一种有用的方式捕获InterruptedException,该异常允许任务中断工作并在需要时重置中断标志。ExecutorService实现具有shutdownNow方法,该方法将中断当前任务。

这是一个如何使用interrupt停止线程的示例。



 类似资料:
  • Apache Tomcat说过很多次: web应用程序[/MyServlet]似乎已启动名为[pool-61-thread-2]的线程,但未能停止该线程。这很可能会造成内存泄漏。 这样危险吗?servlet应该能够每天处理10.000个请求。如何关闭线程时,他们已经完成?

  • 问题 你要为需要并发执行的代码创建/销毁线程 解决方案 threading 库可以在单独的线程中执行任何的在 Python 中可以调用的对象。你可以创建一个 Thread 对象并将你要执行的对象以 target 参数的形式提供给该对象。 下面是一个简单的例子: # Code to execute in an independent thread import time def countdown(

  • 我正在使用org.AsynchTtpClient发布异步请求。 在关闭tomcat时,我得到了以下日志: 严重:web应用程序[/test]似乎启动了一个名为[pool-1-thread-1]的线程,但未能停止它。这很有可能造成内存泄漏。 2017年7月4日10:53:00 AM org.apache.catalina.loader.webappclassloaderbase clearRefer

  • 我在log4j v1中面临内存泄漏的问题。如何解决这个内存泄漏问题。此方法是定期检查log4j.properties文件在我的类中的更新。 PropertyConfigutaror.ConfigureandWatch(time_ms); 但是在关机期间,tomcat内存泄漏问题就来了。日志如下: 提前致谢

  • 对不起,老问题。我已经澄清了。我如何用我可怜的线程类开始停止线程? 编辑:它在循环中,我想在代码开头再次重新启动它。我如何启动停止重新启动? 我的班级: 在主代码中,我希望:

  • 我的Optaplanner似乎出现了内存泄漏。要复制,只需下载Quarkus示例: 然后通过增加终止时间(例如,将)和取消注释表示的行来更改以启用多线程。 然后,运行手册中的请求: 内存使用量开始稳步增加,同时生成了数百万个PhreakPropagationContext对象。我认为这不是预期的行为。我应该为此制造问题还是遗漏了什么?