项目场景:
Java多线程任务,处理数据后写入elasticsearch中。
问题描述:
最开始写入是正常的,过了一段时间间,突然报错
Exception in thread "pool-66-thread-1" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:714)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:337)
at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:194)
at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
at java.lang.Thread.run(Thread.java:745)
原因分析:
-
此问题先翻译报错信息:
java.lang.OutOfMemoryError:无法创建新的本机线程 -
原因很明显:
就是说我们创建的线程太多了,无法创建新的线程了 -
百度看下创建线程数量和啥有关系:
能创建的线程数的具体计算公式如下:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads
MaxProcessMemory 指的是一个进程的最大内存
JVMMemory JVM内存
ReservedOsMemory 保留的操作系统内存
ThreadStackSize 线程栈的大小
原因多半就是:
创建的线程执行业务完后,没有销毁线程(或者没有归还线程资源),而线程却一直创建,最后无法创建失败报错。
解决方案:
- 拿到出问题ar包,本地运行。
- 使用本地jdk自带工具jconsole 查看程序运行状况。
果然发现,线程一直在增加。确认之前的想法,线程资源没释放,而且一直在创建线程。
- 最后在代码里找到,发现问题所在。使用RestHighLevelClient连接es后,做完业务操作后,为使用close关闭。
private static void closeClient(RestHighLevelClient client) {
if (client!=null){
try {
client.close();
} catch (IOException e) {
logger.error(e.getMessage(),e);
}
}
}
本类问题,只要顺着这个思路去找寻定位问题,就可以解决。希望对你有帮助!