欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 手游 > 记一次因ThreadPoolExecutor多线程导致服务器内存压满问题

记一次因ThreadPoolExecutor多线程导致服务器内存压满问题

2025/8/20 18:57:38 来源:https://blog.csdn.net/xlc6011/article/details/140184732  浏览:    关键词:记一次因ThreadPoolExecutor多线程导致服务器内存压满问题

经过下载服务器内存数据得知是通过多线程业务处理查询list集合数据没有得到正确释放导致的。

首先先了解一下list集合数据的存放和回收(可能说的不对,请谅解【挠头】)

存放:

        当我们创建一个list或者从数据库查询出的数据用list集合进行接收时,比如

                List<User> user = new ArrayList<User>;

                user.add("张三");

                user.add("李四");

                user.add("王二麻子");

        这个时候我们实际上是在堆内存中创建了一个list实例,并将list的引用放在栈内存的变量中

        user是一个引用,存放在栈内存中,List<User>对象以及集合里的元素("张三","李四","王二麻子")存放在堆内存里。

回收:

        当我们业务处理完成,且调用方法执行结束后,伟大而又优秀的gc就会把内存里的数据回收掉,来释放内存空间。

好,接下来进入今天的正题,废话不多说,直接贴代码

public void autoMatic() throws InterruptedException {List<ChannelShopTemplate> template = baseService.list();//查询关联商城模板的渠道int taskCount = template.size();int maxThreadCount = template.size(); // 最多同时执行多少个任务ThreadPoolExecutor executor = new ThreadPoolExecutor(maxThreadCount, // 核心线程数和最大线程数都为5maxThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());for (int i = 0; i < taskCount; i++) {executor.submit(new Task(template.get(i).getTemplateId()));System.out.println("当前线程池中线程数:" + executor.getPoolSize());// 如果当前线程池中的线程数量已经达到最大线程数,暂停1秒钟后继续添加任务while (executor.getPoolSize() == maxThreadCount) {Thread.sleep(1000);}}executor.shutdown();}

每个线程都会从数据库查询大量数据,如果能正常释放回收,那么就没问题,

经过模拟排查定位出服务器内存压满的原因就是压根没回收,中间的一行代码Thread.sleep(1000);因为用的是while就会一直在这里睡,直接眼睛一闭不睁了,所以导致后面线程关闭和gc回收工作就卡住了。问题解决,心也碎了。

行了,结束,今天就到辶

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com