问题处理记录与深入:系统线程耗尽,Java无法调用native方法新建线程

1. 问题处理记录

1.1 问题描述

  • 公司使用Presto作为OLAP查询引擎,Presto的coordinator节点在运行过程中报错

    java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reachedat java.base/java.lang.Thread.start0(Native Method)at java.base/java.lang.Thread.start(Thread.java:802)
    
  • 当时,第一反应:有了异常堆栈,大概知道是哪里发生了线程滥用,这是测试环境,先立马重启服务后观察下线程增长情况

  • 重启服务后,不停执行如下命令,发现对应Java进程的线程使用量确实再不断增加

cat /proc/${pid}/status | grep "Threads"

1.2 问题修复与观察

  • 问题原因: 通过异常堆栈,发现是某个方法不停新建HttpClient、却又没有进行close导致

  • 问题修复后,通过如下shell脚本观察线程使用情况:每隔10min打印一次线程数

    #!/bin/bashwhile true
    doecho -ne $(date +%Y-%m-%dT%H:%M:%S)" "cat /proc/${pid}/status | grep "Threads" # 使用时,${pid}替换成对应的Java服务进程号sleep 10m
    done
    
  • 定时执行shell脚本,发现线程数得到了控制,观察4小时,最大线程数699 —— 问题成功修复

    nohup ./watch_threads.sh > threads_stat.txt 2>&1 &
    

    在这里插入图片描述

2. 疑问:一个Java进程究竟能创建多少线程?

  • 后来,使用ulimit -a查看系统资源配置时,发现系统允许root用户可以创建的最大进程或线程数为unlimited

  • 因此,笔者有了疑惑:

    • 既然是unlimited,为何会出现unable to create native thread的情况?
    • 还有,从系统资源有限的角度来说,这里的unlimited不应该是无上限,而是相对具体的、类似65636这样的固定值来说,只要系统资源未耗尽就可以创建线程
  • 可惜的是,笔者当时并未查看报错时的线程数,无法判断这个unlimited的上限究竟是多少

2.1 优秀文章的启发:How Many Threads Can a Java VM Support?

  • Baeldung的一篇文章:How Many Threads Can a Java VM Support?,让笔者大概有了一个认识
  • JVM,即一个Java进程,能创建的最大线程数,至少有两个方面的决定因素:
    • JVM本身 + 系统内存
    • 操作系统限制

2.2 决定因素1:JVM本身 + 系统内存

  • JVM中,堆栈的max size由-Xss-XX:ThreadStackSize进行设置
    -Xss1024k # 如果省略unit,默认unit:Byte
    -XX:ThreadStackSize=1024 # unit:KB
    
  • JVM会为每个线程创建自己的堆栈,创建堆栈使用的内存为系统内存,并非JVM Heap memory
  • 因此,有如下计算公式
    • MaxProcessMemory:是指进程的最大寻址空间
    • ReservedOsMemory:保留的操作系统内存,如Native Heap、JNI之类,一般100MB
    Number of threads = (MaxProcessMemory - JVMHeapMemory - ReservedOsMemory) / (ThreadStackSize) 
    

2.3 决定因素2:操作系统限制(以Linux系统为例)

  • 首先,Linux系统级对max thread的限制,threads-max

    cat /proc/sys/kernel/threads-max # 服务器上的threads-max = 6179160
    
  • 其次, Linux系统在内核级别将线程视为进程,因此限制最大进程数的pid_max也会影响JVM可以创建的线程数量

  • 这也是为什么ulimit -a展示的max user processes也被视为线程数限制的原因

    cat /proc/sys/kernel/pid_max # 相对threads-max,值更小,4194303
    
  • 还有,vm.max_map_count 参数,它指定进程可以拥有的虚拟内存区域 (VMAs,Virtual Memory Areas) 的最大数量

    cat /proc/sys/vm/max_map_count # 三者中,max_map_count的值最小,2097152
    
  • 最后,Linux支持针用户级别的资源限制,可以通过ulimit -a查看当前用户的资源限制。其中,max user processes的值也限制了JVM能创建的最大线程数

2.4 总结

  • JVM能创建的最大线程数是由各种因素综合决定的,且一定是这些因素中的min value决定
  • 决定因素1触发unable to create native thread,其根因是内存不足
  • 决定因素2中触发unable to create native thread,其本质是系统资源限制

3. 后记

  • 后续,如果有机会可以学习:
    • 如何触发unable to create native thread
    • 如何调整JVM参数、Linux系统的线程limit,从而验证这些影响因素
  • 一些优秀参考链接:
    • 启蒙文章:How Many Threads Can a Java VM Support?
    • unable to create new native thread 问题处理,指出了该出现错误的两种原因:内存不足达到线程数限制
    • Maximum Number of Threads per Process in Linux
    • How to Get the Number of Threads in a Java Process,可以学习如何通过ps命令查看线程数
    • 非常简单的触发unable to create native thread错误的demo:java jvm 最大线程数设置
    • 对决定因素1中计算公式的介绍:JVM最多能创建多少个线程: unable to create new native thread

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/38252.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习】InST,Inversion-Based Style Transfer with Diffusion Models,论文,风格迁移,实战(二)

什么是文本反演? 文本反演:通过几张反映特定概念的图像,教基础模型新的词汇。 这个概念可以是:一个姿势、一种艺术风格、一种纹理等。这个概念不一定要在现实世界中实际存在。例如,您可能见过许多生成的图像&#xf…

Google推出开源模型Gemma 2:性能大幅提升与创新训练方法

引言 近日,Google推出了开源模型Gemma 2,吸引了广大研究人员和开发者的关注。相比上一代模型,Gemma 2在性能和可用性方面实现了显著提升,提供了9B和27B两个版本,并且对外开放免费使用。本文将深入探讨Gemma 2的技术细…

架构师篇-10、DDD实战篇:通过领域模型落地系统

基于领域模型的设计与开发 数据库设计程序设计微服务设计 在线订餐系统的领域事件通知 微服务拆分 事件风暴会议 梳理领域事件进行领域建模识别聚合关系划分限界上下文 用户下单领域模型 更新后的模型 领域模型的设计实现过程 数据库设计 数据库映射:一对一关系…

SpringBoot使用redis 笔记(视频摘抄 哔哩哔哩博主(感谢!):遇见狂神)

springboot集成redis步骤 1.创建springboot项目 2.配置连接 3.测试 创建springboot项目 创建以一个Maven项目 创建之后查看pom.xml配置文件,可以看到 pom文件里面导入了 data-redis 的依赖,那我们就可以在知道,springboot集成redis操作…

计算机基础之汇编语言学习笔记

学习来源:b站各种学习资料 前置知识:计算机组成原理等知识 学习参考的资源 汇编语言编程的速成指南[上]~从零开始的期末抢救计划 (8086汇编)_哔哩哔哩_bilibili 链接: https://pan.baidu.com/s/1tg_ZW7VD3TS_s1v_EjS89w?pwdak6…

Uniapp 默认demo安装到手机里启动只能看得到底tab无法看到加载内容解决方案

Uniapp 默认demo安装到手机里以后,启动APP只能看到底tab栏,无法看到每个tab页对应的内容,HBuilder会有一些这样的报错信息: Waiting to navigate to: /pages/tabBar/API/API, do not operate continuously: 解决方案:…

目标追踪的基石:深度解析边界框(Bounding Box)

标题:目标追踪的基石:深度解析边界框(Bounding Box) 摘要 在计算机视觉和图像处理领域,边界框(Bounding Box)是一种用于目标检测和目标追踪的基本工具。它通过矩形框的形式,精确地…

分治精炼宝库-----快速排序运用(⌯꒪꒫꒪)੭

目录 一.基本概念: 一.颜色分类: 二.排序数组: 三.数组中的第k个最大元素: 解法一:快速选择算法 解法二:简单粗暴优先级队列 四.库存管理Ⅲ: 解法一:快速选择 解法二:简单粗…

Unity扩展编辑器功能的特性

1.添加分组标题 用于在Unity的Inspector视图中为属性或变量组创建一个自定义的标题或头部,有助于在Inspector中组织和分类不同的属性,使其更易于阅读和管理。 [Header("Common Properties")] public float MouseSensitivity 5; public float…

ES中单机部署状态为Yellow解决办法

一、背景 单机的 ES 状态为 Yellow,在 Kibana 的管理界面看到的 index 的状态也是 Yellow 这个问题在于单机版的 ES,是没有备份的,没有副本,设置 index 副本的数量为 0 即可 PUT /index/_settings {"number_of_replicas&q…

家里装修网线的三种预留方式你需要提前知道,避免后悔

聊一下网线。如果让你一天不吃饭你可能受得了,让你一天不喝水你也能受得了,如果让你三个小时不上网,估计很多人都受不了。      因为现在每个人都太依靠网络了,人人都有“网瘾”。所以在装修中,业主对家里的网络关…

学习java第一百一十六天

Spring Framework有哪些不同的功能? 答: 轻量级-Spring 在代码量和透明度方面都很轻便。 IOC-控制反转AOP-面向切面编程可以将应用业务逻辑和系统服务分离,以实现高内聚。容器-Spring 负责创建和管理对象(Bean)的生命周…

Python· 求解一元二次方程实根的函数

在Python中,求解一元二次方程 ( ax^2 bx c 0 ) 的实根可以通过使用math模块中的sqrt函数来实现。这里提供一个简单的函数,它接受三个参数a、b和c,然后返回方程的实根。 import mathdef solve_quadratic(a, b, c):# 计算判别式的值discrim…

微服务中的Docker详细学习

Docker的个人理解 首先我对于Docker的理解分为两部分,第一是对名字上的理解,我们都知道docker的英文翻译是“码头工人”的意思,所以我们也可以理解为docker是码头上的一个个集装箱的使用。这也与他的图标很相似。其次我是对于其功能上的理解&…

计算机网络-第3章数据链路层

信道类型:①点对点信道,一对一的点对点通信方式。②广播信道,一对多的广播通信方式,过程比较复杂。 3.1数据链路层的几个共同问题 3.1.1数据链路和帧 链路就是从一个节点到相邻节点的一段物理线路,而中间没有任何其…

Redis 高可用(理论)

目录 Redis 高可用 Redis 持久化 RDB 持久化 触发条件 手动触发 自动触发 ##其他自动触发机制## 执行流程 启动时加载 AOF 持久化 执行流程 (1)命令追加(append) (2)文件写入(write)和文件同步(sync) (3&…

帝国CMS(EmpireCMS)漏洞复现

简介 《帝国网站管理系统》英文译为Empire CMS,简称Ecms,它是基于B/S结构,且功能强大而帝国CMS-logo易用的网站管理系统。 帝国CMS官网:http://www.phome.net/ 参考相关漏洞分析文章,加上更详细的渗透测试过程。 参考…

snat、dnat和firewalld

目录 概述 SNAT源地址转换 DANT目的地址转换 抓包 firewalld 端口管理 概述 snat :源地址转换 内网——外网 内网ip转换成可以访问外网的ip 也就是内网的多个主机可以只有一个有效的公网ip地址访问外部网络 DNAT:目的地址转发 外部用户&#…

人工智能导论速成笔记

文章目录 前言考试题型第一章、人工智能导引 (10分 )课后习题第二章、Python基础 (10分 )*文件读写NumPy的使用Python绘图基础第三章、机器学习初步(15分 )逻辑回归分类(Logistic Regression)*,3.5线性回归预测(Linear Regression)*,3.6 、3.7、 3.8聚类 3.9第四章、自然语言…

一文带你了解乐观锁和悲观锁的本质区别!

文章目录 悲观锁是什么?乐观锁是什么?如何实现乐观锁?什么是CAS应用局限性ABA问题是什么? 悲观锁是什么? 悲观锁它总是假设最坏的情况,它会认为共享资源在每次被访问的时候就会出现线程安全问题&#xff0…