当前位置: 首页 > news >正文

解决 java.lang.OutOfMemoryError: unable to create new native thread

这个异常问题本质原因是我们创建了太多的线程,而能创建的线程数是有限制的,导致了异常的发生。

注意:能创建的线程数的具体计算公式如下:

(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

MaxProcessMemory 指的是一个进程的最大内存 JVMMemory JVM内存 ReservedOsMemory 保留的操作系统内存 ThreadStackSize 线程栈的大小

在java语言里, 当你创建一个线程的时候,虚拟机会在JVM内存创建一个Thread对象同时创建一个操作系统线程,而这个系统线程的内存用的不是JVMMemory,而是系统中剩下的内存(MaxProcessMemory - JVMMemory - ReservedOsMemory)。

所以,由公式得出结论:你给JVM内存越多,那么你能创建的线程越少,越容易发生 java.lang.OutOfMemoryError: unable to create new native thread。

每new一个Timer会启动一个线程,如果使用在循环或者递归当中,很容易造成JVM报如下错误:

java.lang.OutOfMemoryError: unable to create new native thread

最后采用的是线程池办法Executors.newScheduledThreadPool(),避免用new Timer()

并且把改为接将这个变量改为静态变量,避免每次都初始化线程池

Timer和TimerTask的简单组合是多线程的嘛?不是,一个Timer内部包装了“一个Thread”和“一个Task”队列,这个队列按照一定的方式将任务排队处理,包含的线程在Timer的构造方法调用时被启动,这个Thread的run方法无限循环这个Task队列,若队列为空且没发生cancel操作,此时会一直等待,如果等待完成后,队列还是为空,则认为发生了cancel从而跳出死循环,结束任务;循环中如果发现任务需要执行的时间小于系统时间,则需要执行,那么根据任务的时间片从新计算下次执行时间,若时间片为0代表只执行一次,则直接移除队列即可。

Java的一个Timer对象本身只有一个线程,如果向他提交多个task,并且某个task相当耗时的话,其他的task即使到了执行时间,仍然会等之前的task执行完毕。更有问题,如果前一个task抛出了异常导致线程终止,后面的task将无法执行。

Java5以后推荐采用java.util.concurrent的ScheduledExecutorService,至少能避免异常导致线程结束的问题。 (ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1)) 如果对时间有比较准确的需要,务必一个ScheduledExecutorService处理一个任务。

相关文章:

  • 做网站需要续费吗/网站优化的方法有哪些
  • 找人网站/免费注册
  • 网站开发使用什么运行软件/网站免费建站app
  • 电子商务网站建设作文/企业网络推广方案
  • 推荐网站建设服务商/西安抖音seo
  • 网站右下角图片代码/网站排名首页
  • 【封装代码】
  • ATWebshell:基于对抗学习和长短语义感知的Webshell检测方法
  • 使用FileInputStream + FileOutputStream完成文件拷贝
  • 小米便签维护过程记录——可能出现问题解决方案
  • clickhouse笔记05--快速部署3节点集群
  • 如何确定企业是否需要推行CMMI?
  • Typora使用之在腾讯云建立远程图床【多图】
  • 【Linux操作系统】多线程(一)
  • 快速部署PHP Web环境(nginx php mysql redis)
  • Gadget-2在一个加速卡异构平台上的移植与优化
  • 【矩阵论】7.范数理论——基本概念——矩阵范数生成向量范数谱范不等式
  • 还有1个月,乘用车搭载首超5百万辆!L2/L2+前装交付一路狂奔