解决java.lang.OutOfMemoryError: unable to create new native thread 原创 2021-04-08 10:40:19.0 阅读(3373)次 #### 异常问题 项目并发测试一个功能时报创建不了本地线程,如下: ``` Caused by: java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:717) at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:957) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1367) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) at cn.com.datu.search.impl.AccompanyPersonSearchImpl.initFaceSameWayList(AccompanyPersonSearchImpl.java:113) at cn.com.datu.service.impl.ResultRecordServiceImpl.queryFaceSameWayDataList(ResultRecordServiceImpl.java:444) at cn.com.datu.controller.FaceSameWayController.query(FaceSameWayController.java:119) at sun.reflect.GeneratedMethodAccessor221.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ... 59 common frames omitted ``` #### 解决过程 看到OutOfMemoryError,我们就会想到内存不足,但是项目里的这个功能应该吃不了太多内存,主要是数据库操作。 再看unable to create new native thread,难道是线程栈内存给高了?看了下项目启动的内存配置信息,如下: ``` -Xms2048m -Xmx2048m -Xss512K ``` -Xss也只给了512,应该不大啊。没有解决问题的头绪。 这个功能是我一个同事开发的,并不是我,我只好硬着头再看看对应的代码,发现代码里每次HTTP请过来都会创建一个线程池来处理这次请求,问了同事才知道这是为了加快处理请求而加上了多线程处理。 看了下每次请求会创建线程数为30的线程池,并发请求10就是10*30个线程会被创建出来。占用内存只有150MB左右,应该不是内存不够的问题。 我将他线程池改为10个线程(原先30个),再用10并发请求测试一下,发现持续并发一会还是会报创建不了线程。应该是有什么其他问题影响了。 再想了下线程跟文件句柄有关,看了下docker里的最大打开文件数,再看看宿主机的打开文件数配置,都还正常。(我们项目运行在K8s上面)  如上图所示,open files数字还挺大的,我们这个测试场景达不到这么高,所以也排除系统参数问题。 这时只好在并发测试过程中,使用jstack命令将jvm线程信息导出定位问题了。 由于测试刚开始不会报错,需要持续2分钟左右才会报创建不了本地线程,所以我用jstack在这2分钟中内分别导出了4份线程栈信息,命令如下: ```shell jstack -l 1 > /jstack1.txt ``` 然后叫运维把这4份日志从容器中复制出来给我,我统计了下并发测试的功能线程池对应的线程数最高的日志中居然有600多个,按理说10个并发乘以一个池10个线程数总线程数量不会超过100个啊,这怎么是600多个!!  当然也可以用如下简单命令查看对应线程数量,前提是线程池取了对应名称,统计jvm中业务线程命令如下: ```shell jstack -l 1 > /jstack.txt && grep -o "线程名" /jstack.txt | wc -l ``` 所以问题已经很明显了,应该是线程没有被正常回收,有泄漏。 再看看同事写的线程池代码,如下: ```java //创建线程池 ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("face-same-way-%d").build(); ThreadPoolExecutor executor = new ThreadPoolExecutor(accompanyPersonThread, accompanyPersonThread, 0, TimeUnit.SECONDS, new LinkedBlockingQueue(1024),factory); List> threadList = new ArrayList<>(); for (int i = 0; i < dateList.size(); i++) { ... //提交任务 threadList.add(executor.submit(new AccompanyPersonAnalysisThread(dto))); } for (Future future : threadList) { future.get(30, TimeUnit.SECONDS); } threadList.clear(); ``` 这时我才顿悟,线程池没有shutdown!! 如果不shutdown,不主动关闭线程池的话,池里会有些休眠的线程,通常会在1分钟以后再被关掉,然后就出现了上面的从100个线程慢慢堆积到了600个线程了。 修改代码,加上shutdown: ```java executor.shutdown(); while (!executor.isTerminated()) { TimeUnit.MILLISECONDS.sleep(100L); } ``` 再用10个和30个并发都不会再出现无法创建线程了。 java 异常处理 jvm 上一篇:postgresql数据库表分区字段有必要创建索引么? 下一篇:LinkedBlockingQueue实现定长队列自动出队与读取队列
相关文章 记一次maven报错解决:Failed to read artifact descriptor for com.aliyun.openservices:aliyun-openservices:jar:2.0.0-OTS(6018) java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener(1480) elasticsearch7.1保存时报错: Validation Failed: 1: type is missing;(11274) Es创建索引mapping时报错:Root mapping definition has unsupported parameters: [doc(8934) windows nginx启动报错bind() to 0.0.0.0:80 failed (2276) solr搜索报错:Error from server at http://127.0.0.1:8983/solr/索引名: undefined field text(5731) Got error: 2002: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) when trying to connect(2989) Es 7.x版本批量写入数据路由字段报错:Action/metadata line [1] contains an unknown parameter [_routing](4026) Parameter index out of range (1 > number of parameters, which is 0(1864) seata并发测试报错:get global lock fail, xid:192.168.64.1:18091:2025291279, lockKeys:stock_info:1(8125) 推荐文章 使用spring4实现websocket连接(1) Parameter index out of range (1 > number of parameters, which is 0(7) spring cloud+feign+mybatis中使用seata0.9实现分布式事务(7) spring cloud gateway报错Only one connection receive subscriber allowed(82) spring cloud中Feign调用诡异报错MethodNotAllowed: status 405 reading(116) elasticsearch7.1保存时报错: Validation Failed: 1: type is missing;(7) 聊聊数据保存到MySQL后数据乱码的问题(1) jquery对象与dom对象互转(1) linux使用epel源yum安装iftop、nload、nginx等(2) linux下nginx安装其他模块(1) 热门文章 java stream去重的几种方式(40819) the dependencies of some of the beans in the application context form a cycle(16324) 解决mybatis打印查询结果集造成太多日志的问题(9839) java enum枚举转list和Map(9722) java stream List转Map与List转List与Map转List以及List转Map(8468) ServletRequest转HttpServletRequest设置header之后取不到header的问题(8434) java中BufferedImage转成 base64字符串(8098) 切分List集合为多个List集合(7385) maven修改jar包版本不生效解决办法(6990) bootstrap.yml配置报错:Could not resolve placeholder 'xx' in value (6949) 标签列表 java java java java java java java基础 微服务 异常处理 mysql clickhouse clickhouse clickhouse clickhouse clickhouse spring cloud spring boot linux elasticsearch feign jdbc spring js docker postgresql solr seata nginx maven gateway hsqldb 数据库 架构 大数据分析 分布式事务 redis canal dubbo hadoop 消息队列 win10 websocket springmvc git html select2 mybatis jenkins rocketmq quartz activemq 数据库集群 ajax bat 电脑 笔记 eclipse 设计模式 阿里云 github freemarker jvm jquery javamail redission redission对象 hystrix http hibernate springmail svn ubuntu ueditor xheditor zookeeper 分布式 小程序 开发工具 gitlab