pthread_create创建线程失败问题排查

news2025/2/24 8:55:57

一些基础概念的了解

Android中线程(Thread)的创建及内存分配过程分析
pthread_create创建线程失败的OOM详解
不可思议的OOM
通过上面的文章,我们知道为什么会报pthread_create错误

在创建线程的时候,报的下面这些错误,都是linux系统层面的导致的错误,而不是在虚拟机层面,在java中创建一个线程,最终是在linux操作系统上创建了一个线程

  • 错误类型一:
    java.lang.OutOfMemoryError: Could not allocate JNI Env
    JNIENV创建不成功时产生OOM的错误信息为"Could not allocate JNI Env"
    有如下可能的两种情况:
    (1)用户态虚拟内存地址空间耗尽,mmap创建失败
    (2)FD数超限导致

  • 错误类型二pthread_create:
    调用C库创建线程时的环节,创建线程首先调用__allocate_thread函数申请线程私有的栈内存(stack)等,采用的是mmap的方式,然后调用clone方法进行线程创建。
    java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory
    pthread_create失败时抛出OOM的错误信息为"pthread_create (%s stack) failed: %s"
    Try again 是申请线程栈内存的时候,失败了
    Out of memory 是在clone线程的时候,创建线程数超过了设置的最大线程数

我们遇到的问题

Manufacturer : samsung
Model : SM-F9360
SdkInt : 32
ProcessorNumber : 8


java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
	at java.lang.Thread.nativeCreate(Native Method)
	at java.lang.Thread.start(Thread.java:884)
	at java.util.Timer.<init>(Timer.java:167)
	at com.ksyun.media.streamer.logstats.StatsLogReport.c(StatsLogReport.java:3)
	at com.ksyun.media.streamer.logstats.StatsLogReport.startStreamSuccess(StatsLogReport.java:16)
	at com.ksyun.media.streamer.publisher.RtmpPublisher$1.run(RtmpPublisher.java:17)
	at android.os.Handler.handleCallback(Handler.java:938)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loopOnce(Looper.java:226)
	at android.os.Looper.loop(Looper.java:313)
	at android.app.ActivityThread.main(ActivityThread.java:8855)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

Exception occurs first time, date is :2022/10/26 12:55:47

大老板在直播的时候,app崩溃了
发现是pthread_create的时候,try again类型错误导致的崩溃,通过上面查阅的各种信息来看,try again这种错误,按道理是很少遇到的,很多文章对这种错误都是附带的提了一下。因为,这是线程申请内存导致的错误,现在的机器物理内存都很大,何况线程申请内存是向虚拟内存申请的,对于64位的机器,虚拟内存会更大,可以超过实际的物理内存。SM-F9360 是三星最新出的折叠屏手机,64位的12G内存的。怎么会有虚拟内存不足的问题出现呢?

在不可思议的OOM文章中,有一段这样的描述:
在这里插入图片描述
也就是说,在32位的机器上,由于进程可用的虚拟(逻辑)地址空间最多只有3G,创建线程时,很有可能报try again错误,可是,我们遇到try again的机器是64位呀!

排查这问题时,我有些无助和疲惫,压力很大,首先,这是我们大老板遇到的问题,而且,领导还和我说这个问题“紧急且重要”,这。。。二来,这个错误报错在linux层,我对C++了解程度都有限,心里觉得自己够呛能解决,三来,我当时还有点感冒低烧头疼。可想,我当时的状态有多糟糕,可是,问题还是得解决,欲哭无泪!!!

继续回到解决问题的话题上来吧。在看C++代码的时候,语法问题,请教了一下做C++方面工作的同事,同事无意说他们之前遇到一个问题是,32的程序跑在64位的机器上,会有内存不足的问,我一想,我们会不会也有这个问题啊???
32位的程序跑在64位的机器上,机器会按照32位来运行,也就是说最大虚拟地址空间是3G。

android apk也是有32和64位区分的,进一步来说,其实是包含的so库有32位和64位的区分。理解到,我们的apk包会单独打只包含32位或64位so库的,然后按照渠道要求上传,现在很多商品都要求是64位的。了解到大老板安装的apk包是从官网下载在,官网只是32位的包。

破案了,普天同庆呀,很大概率就是这个原因,没想到能解决这个问题,自己瞬间轻松了,感觉天亮了,太难了。

疑问汇总

32位和64位

最常见的就是 32位和64位的问题了。

CPU 通过物理总线访问内存,那么访问地址的范围就受限于机器总线的数量,在32位机器上,有32条总线,每条总线有高低两种电位分别代表 bit 的 1 和 0,那么可访问的最大地址就是 2^32bit = 4GB,所以说 32 位机器上插入大于 4G 的内存是无效的,CPU 访问不到多于 4G 的内存。

但 64位机器并没有 64位总线,而且其最大内存还要受限于操作系统,Linux 目前支持最大 256G 内存。

根据虚拟内存的概念,在 32 位系统上运行 64 位软件也并无不可,但由于系统对虚拟内存地址的结构设计,64位的虚拟地址在32位系统内并不能使用。

用户态虚拟地址空间和内核态虚拟地址空间

在操作系统中引入了虚拟内存的概念,所以,很多概念都是针对虚拟内存说的,比如用户态、内核态。

进程的虚拟地址空间分为用户区(0-3G)和内核区(3-4G), 其中内核区是受保护的, 用户是不能够对其进行读写操作的;

内核区对于所有进程是共享的;系统中所有进程对应的虚拟地址空间的内核区都会映射到同一块物理内存上(系统内核只有一个)。

在这里插入图片描述
虚拟地址空间中用户区地址范围是 0~3G,里边分为多个区块:

保留区: 位于虚拟地址空间的最底部,未赋予物理地址。任何对它的引用都是非法的,程序中的空指针(NULL)指向的就是这块内存地址。
.text段: 代码段也称正文段或文本段,通常用于存放程序的执行代码 (即 CPU 执行的机器指令),代码段一般情况下是只读的,这是对执行代码的一种保护机制。
.data段: 数据段通常用于存放程序中已初始化且初值不为 0 的全局变量和静态变量。数据段属于静态内存分配 (静态存储区),可读可写。
.bss段: 未初始化以及初始为 0 的全局变量和静态变量,操作系统会将这些未初始化的变量初始化为 0
堆(heap):用于存放进程运行时动态分配的内存。
堆中内容是匿名的,不能按名字直接访问,只能通过指针间接访问。
堆向高地址扩展 (即 “向上生长”),是不连续的内存区域。这是由于系统用链表来存储空闲内存地址,自然不连续,而链表从低地址向高地址遍历。
内存映射区(mmap):作为内存映射区加载磁盘文件,或者加载程序运作过程中需要调用的动态库。
栈(stack): 存储函数内部声明的非静态局部变量,函数参数,函数返回地址等信息,栈内存由编译器自动分配释放。栈和堆相反地址 “向下生长”,分配的内存是连续的。
命令行参数:存储进程执行的时候传递给 main() 函数的参数,argc,argv [],env[]
环境变量: 存储和进行相关的环境变量,比如:工作路径,进程所有者等信息

从上面的概念,知道java虚拟机进程中管理分配对象和自动回收的堆内存,是在linux虚拟地址空间的堆(heap)空间这块区域。自己,在初次接触虚拟内存概念的时候,就一直有个问题,困扰着我,linux的虚拟内存和虚拟机的堆内存是个什么关系?

我个人理解,java程序是跑着虚拟机里面的,虚拟机对于linux来说就是一个进程,也就是,一个apk都需要一个虚拟机,apk+虚拟机,作为一个进程跑在linux操作系统上。虚拟机会向linux申请一大块虚拟内存,这个虚拟内存就是上图一个完整的用户区虚拟内存,然后,虚拟机自己管理的堆内存就是在虚拟内存的堆所在的空间。
在这里插入图片描述

自己实际测试

我们64位的包安装到64位的机器上,VIRT虚拟内存10G,我这手机物理内存是8G,RES实际使用内存200M
在这里插入图片描述
32位的包安装到64位的机器上,VIRT虚拟内存只有2.6G,而且还得分成很多块做不同用途,所以很容易出现内存问题
在这里插入图片描述

参考

Linux虚拟内存这样理解就到位了
Liunux内核内存管理之虚拟地址空间
JVM和Linux内存的关系
吐血推荐–Linux与JVM的内存关系分析
Android 进程监控(top命令)
java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
经典 OOM 问题|pthread_create
《Android 创建线程源码与OOM分析》
OutOfMemoryError pthread_create (1040KB stack) failed Try again
快速缓解 32 位 Android 环境下虚拟内存地址空间不足的“黑科技”

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

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

相关文章

SAP采购订单中的净价是单价还是总价?

在采购订单中习惯上我们把订单项目的的净价理解为什么&#xff1f;单价还是总价&#xff1f; 先不着急回答。看看以下两个采购订单的对比截图就能了解&#xff0c; 在4050004000这笔采购订单中&#xff0c;采购10件黄色箱子&#xff0c;每10件500元。所以&#xff0c;净价500…

《JavaSE-第十七章》之LinkedList

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 刷题求职神器 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水…

Python Excel导入Mysql的通用方法

文章目录一、前言二、实现一、前言 此代码将导入部分尽量通用&#xff0c;仅配置下面两项就可以进行导入了&#xff1a; 从哪个excel导入到哪个mysql表 在程序中配置 他们之间的字段如何对应 写在mysql表中 ps&#xff1a;id&#xff0c;create_time&#xff0c;update_tim…

基于IDEA创建SpringBoot项目并进行入门分析

基于IDEA创建SpringBoot项目并进行入门分析 文章目录基于IDEA创建SpringBoot项目并进行入门分析SpringBoot 项目创建创建Module项目结构分析SpringBoot 项目启动分析启动入口启动过程概要分析SpringBoot 快速入门分析业务描述API设计分析代码编写及运行运行过程中的BUG分析Spri…

单商户商城系统功能拆解26—营销中心—限时秒杀

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

数电学习(六、时序逻辑电路)(三)

文章目录时序逻辑电路的设计方法同步时序逻辑电路的设计方法一般步骤改进步骤例&#xff1a;蚂蚁走迷宫背景分析继续编码状态&#xff0c;然后写出状态图&#xff0c;然后卡诺图化简&#xff0c;得到方程设计总结时序逻辑电路的设计方法 同步时序逻辑电路的设计方法 一般步骤…

2022最新SpringCloud面试题附完整答案

一、选择题 1.启动Ribbon的类注解是: ( ) A RibbonClient B EnableClient C EnableDisscoveryClient D Ribbon 2.下面哪个注解不是SpringbootApplication包含的默认属性值&#xff1a;&#xff08; &#xff09; A: Configuration B: EnableAutoConfiguration C: ComponentSc…

【LINUX】Linux最常用的20个基本指令 介绍~分析

什么是 Linux ​ Linux 是一款基于 GNU 通用公共许可协议 的 自由和开放源代码 的类UNIX操作系统&#xff0c;该操作系统的内核由 Linus Torvalds 在1991年首次发布。之后&#xff0c;在加上用户空间的应用程序之后&#xff0c;就成为了Linux操作系统。 但是&#xff0c;严格来…

springboot充电桩综合管理系统

目录 1 绪论 1 1.1 课题背景 1 1.2 课题研究现状 1 1.3 初步设计方法与实施方案 2 1.4 本文研究内容 2 2 系统开发环境 4 2.1 Java技术 4 2.2 JSP技术 4 2.3 B/S模式 4 2.4 MyEclipse环境配置 5 2.5 MySQL环境配置 5 2.6 SSM框架 6 3 系统分析 7 3.1 系统可行性分析 7 3.1.1 经…

基于 BP 神经网络特征提取的指纹识别应用(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑…

【每日训练】排序子序列

目录 题目链接&#xff1a; 输入输出描述&&测试用例&#xff1a; 解析&#xff1a; 程序&#xff1a; 题目链接&#xff1a; 排序子序列_牛客笔试题_牛客网 (nowcoder.com) 输入输出描述&&测试用例&#xff1a; 测试用例&#xff1a; 输入&#xff1a; 6 1…

设计模式之美总结(重构篇)

title: 设计模式之美总结&#xff08;重构篇&#xff09; date: 2022-10-27 17:31:42 tags: 设计模式 categories:技术书籍及课程 cover: https://cover.png feature: false 文章目录1. 概述1.1 重构的目的&#xff1a;为什么要重构&#xff08;why&#xff09;&#xff1f;1.…

10月业务安全月报 | 美国将奇虎360和知道创宇列入黑名单;丰田泄露30万用户信息;苹果曝严重漏洞

导语&#xff1a;随着数字化的深入普及&#xff0c;业务愈加开放互联。企业的关键数据、用户信息、基础设施、运营过程等均处于边界模糊且日益开放的环境中&#xff0c;涉及利益流和高附加值的业务面临多样的安全隐患&#xff0c;随时可能遭遇损失&#xff0c;进而影响企业运营…

HashMap底层源码分析

文章目录HashMap底层源码分析1.观察HashMap成员变量1.1 HashMap的主要成员变量1.2 HashMap的构造方法1.3 put方法HashMap底层源码分析 前言 &#xff1a; 上文我们已经将哈希表学完了&#xff0c;下面就来简单的看一下源码&#xff0c;就结束我们的Map和Set 的学习   1.观察H…

灰度级形态学 - 顶帽变换和底帽变换

目录 1. 介绍 2. 代码实现 1. 介绍 顶帽变换和底帽变换就是图像的加减和开闭运算的结合 顶帽变换的公式为&#xff1a;原图 - 原图的开运算 这里结合开运算的几何图形解释来介绍顶帽变换。 因为开运算是结构元从下往上推动的过程&#xff0c;所以会删除图像灰度值相对周围高…

Dom对象总结案例实操(第二十课)

Dom对象总结案例实操(第二十课) 今天文章有点长 第一部分:回顾之前Dom对象我用了四篇文章对他进行了分开讲述Dom对象的用途,今天用几个案例实操一下. 之前我们Dom对象中了解过下面的内容 Dom对象的定义?Dom对象的节点操作&#xff0c;了解到了父节点 子节点 第一个 子节点 最…

利用Postman测试全屋智能接口

文章目录一、Postman概述二、利用Postman测试全屋智能接口&#xff08;一&#xff09;移动应用开发平台API说明V2.0&#xff08;二&#xff09;下载Postman&#xff08;三&#xff09;启动Postman&#xff08;四&#xff09;测试用户登录接口1、查看用户登录接口说明2、查看登录…

信号完整性测试

信号完整性测试----持续更新中示波器三要素&#xff1a;带宽采样率存储深度IIC信号测试:SPI信号测试USART信号测试RS232信号测试RS485信号测试CAN信号测试PWM信号测试示波器三要素&#xff1a; 示波器三个重要参数&#xff1a;带宽、采样率、存储深度 带宽 示波器的带宽&…

C语言实现windows,linux双版本下的进度条小程序,快来试一试吧

文章目录C语言缓冲区&#x1f680;1.输入缓冲区&#x1f347;模拟登录密码场景&#x1f347;从键盘将内容输入到内存的真正过程&#x1f347;解决方法&#xff1a;清空输入缓冲区&#x1f349;清掉一个字符&#x1f349;清空输入缓冲区所有字符&#x1f680;2.用户C语言级别的缓…

【jenkins部署冲突报错】一定要看!!!!!

背景 最近接手了新的项目&#xff0c;他的代码仓库的分支有点乱&#xff0c;dev、uat、master三个分支代码不同步&#xff0c;差别很大&#xff0c;甚至功能有些也不一样&#xff0c;所以&#xff0c;就导致在合并代码时要注意&#xff0c;最好新切一个分支A&#xff08;同步m…