Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java threadPoolExecutor outOfMemoryException_Java_Multithreading_Concurrency - Fatal编程技术网

Java threadPoolExecutor outOfMemoryException

Java threadPoolExecutor outOfMemoryException,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有一个带有run方法的类,该类的主方法中的计时器正在使用以下代码调用该类: Timer timer = new Timer(); timer.scheduleAtFixedRate(new LegacySmsSender(), 0, 2*1000); 在run方法中,我声明了一个ThreadExecutorPool: ThreadPoolExecutor packetProcessorThreadPool = new ThreadPoolExecutor(4,

我有一个带有run方法的类,该类的主方法中的计时器正在使用以下代码调用该类:

Timer timer = new Timer();
timer.scheduleAtFixedRate(new LegacySmsSender(), 0, 2*1000);
在run方法中,我声明了一个ThreadExecutorPool:

ThreadPoolExecutor packetProcessorThreadPool =
        new ThreadPoolExecutor(4,
                                4,
                                Long.MAX_VALUE,
                                TimeUnit.DAYS,
                                new LinkedBlockingQueue<Runnable>(),
                                new MyThreadFactory("packetProcessorThreadPool")
                                );
在这些PacketProcessor类的run方法中,它们声明了一个ThreadPoolExecutor,并创建和提交了数量在1-5000之间的线程(通常创建6-7个线程),PacketProcessor中的ThreadPoolExecutor代码如下:

ThreadPoolExecutor commonThreadPool =
        new ThreadPoolExecutor(
                        20,
                        20,
                        Long.MAX_VALUE,
                        TimeUnit.DAYS,
                        new LinkedBlockingQueue<Runnable>(),
                        new MyThreadFactory("commonThreadPool"));
threadpool执行器commonThreadPool=
新线程池执行器(
20,
20,
Long.MAX_值,
时间单位:天,
新建LinkedBlockingQueue(),
新MyThreadFactory(“commonThreadPool”);
最后,我运行了大约20分钟,我检查了VisualVM,我的内存使用和实时线程数一直在上升。有什么问题

注意:请随时向我询问更多信息或问题

以下是包含一些信息的屏幕截图:

编辑1:


我获取了270MB的堆转储。我发现了160mb的字符[]。我发现了大约1000-2000000个查询字符串。我使用StringBuilder构建查询字符串。为什么他们没有获得GCD

执行器应该在应用程序启动时声明一次并重新使用。否则,您也可以根据需要创建单个线程。如果在应用程序执行期间继续创建新的执行器,则它们的线程将保持运行,因此线程数将不断增加


因此,只需使用DI框架创建执行器,并将其注入到代码中即可。或者,如果它是一个小项目,将它们放在一个静态字段中。

执行者应该在应用程序启动时声明一次并重新使用。否则,您也可以根据需要创建单个线程。如果在应用程序执行期间继续创建新的执行器,则它们的线程将保持运行,因此线程数将不断增加

因此,只需使用DI框架创建执行器,并将其注入到代码中即可。或者,如果是一个小项目,将它们放在一个静态字段中

在run方法中,我声明了一个ThreadExecutorPool

如果您在run方法中声明ThreadExecutorPool,该方法每2秒执行一次,您将在几分钟内获得许多线程

在run方法中,我声明了一个ThreadExecutorPool


如果在run方法中声明ThreadExecutorPool,该方法每2秒执行一次,那么在几分钟内就会得到许多线程。

问题在于,您已经告诉了所有创建的
ExecutorService
来生成线程,然后让它们永远保持活动状态。这在代码中非常明显:

new ThreadPoolExecutor(
                        20,
                        20,
                        Long.MAX_VALUE,
                        TimeUnit.DAYS,
                        new LinkedBlockingQueue<Runnable>(),
                        new MyThreadFactory("commonThreadPool"));
新线程池执行器(
20,
20,
Long.MAX_值,
时间单位:天,
新建LinkedBlockingQueue(),
新MyThreadFactory(“commonThreadPool”);
第三个和第四个参数基本上是说“让空闲线程(实际上)无限期地保持活动状态”

您可以通过以下两种方式解决此问题:

  • 完成对executor实例的任务传递后,调用ExecutorService.shutdown
  • 最好的解决方案是使用单个
    ScheduledExecutorService
    和更合理的任务分配逻辑来限制线程数量,并通过防止线程上下文切换来提高性能

  • 问题是,您已经告诉了所有创建的
    ExecutorService
    s来生成线程,然后让它们永远保持活动状态。这在代码中非常明显:

    new ThreadPoolExecutor(
                            20,
                            20,
                            Long.MAX_VALUE,
                            TimeUnit.DAYS,
                            new LinkedBlockingQueue<Runnable>(),
                            new MyThreadFactory("commonThreadPool"));
    
    新线程池执行器(
    20,
    20,
    Long.MAX_值,
    时间单位:天,
    新建LinkedBlockingQueue(),
    新MyThreadFactory(“commonThreadPool”);
    
    第三个和第四个参数基本上是说“让空闲线程(实际上)无限期地保持活动状态”

    您可以通过以下两种方式解决此问题:

  • 完成对executor实例的任务传递后,调用ExecutorService.shutdown
  • 最好的解决方案是使用单个
    ScheduledExecutorService
    和更合理的任务分配逻辑来限制线程数量,并通过防止线程上下文切换来提高性能

  • 我尝试将它们用作静态,但它根本没有改变这个分析器上的图像。活动线程从未减少的原因是什么?我尝试将它们用作静态线程,但它根本没有改变这个分析器上的图像。活动线程从不减少的原因是什么?不。在run方法中,我等待线程完成,因此,在第一次运行
    LegacySmsSender
    完成之前,计时器不会再次启动。您的run方法中是否有定期执行的此代码?:ThreadPoolExecutor packetprocessorhreadpool=new ThreadPoolExecutor(…此代码位于计时器执行的操作的run方法中,将其输出到其他位置或执行packetprocessorreadpool.shutdown()操作);在某个地方。如果您将它放在其他地方,然后像@artbristol suggestedno那样创建一次会更好。在run方法中,我会等待线程完成,因此在第一次运行
    LegacySsender
    完成之前,计时器不会再次启动。您的run方法中是否有定期执行的代码?:ThreadPoolExecutorpacketProcessorThreadPool=new ThreadPool Executor(…此代码位于计时器执行的对象的run方法中,该对象将其输出到其他位置或执行packetProcessorThreadPool.shutdown();某个地方。如果你把它放在其他地方,然后像@artbristol suggestedi那样创建一次,那会更好。我在1号上尝试了这个解决方案,在我创建后在TPEs上调用了
    shutdown