JVM源码分析 | 到底有哪些因素决定了一个进程能创建多少线程?_jvm中direct区域影响线程创建吗-程序员宅基地

技术标签: java  linux  编程语言  多线程  大数据  

虽然这篇文章的标题打着JVM源码分析的旗号,不过本文不仅仅从JVM源码角度来分析,更多的来自于Linux Kernel的源码分析,今天要说的是JVM里比较常见的一个问题

这个问题可能有几种表述

  • 一个Java进程到底能创建多少线程?
  • 到底有哪些因素决定了能创建多少线程?
  • java.lang.OutOfMemoryError: unable to create new native thread的异常究竟是怎么回事

不过我这里先声明下可能不能完全百分百将各种因素都理出来,因为毕竟我不是做Linux Kernel开发的,还有不少细节没有注意到的,我将我能分析到的因素和大家分享一下,如果大家在平时工作中还碰到别的因素,欢迎在文章下面留言,让更多人参与进来讨论

从JVM说起

线程大家都熟悉,new Thread().start()即会创建一个线程,这里我首先指出一点new Thread()其实并不会创建一个真正的线程,只有在调用了start方法之后才会创建一个线程,这个大家分析下Java代码就知道了,Thread的构造函数是纯Java代码,start方法会调到一个native方法start0里,而start0其实就是JVM_StartThread这个方法

 
JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) ... // We could also check the stillborn flag to see if this thread was already stopped, but // for historical reasons we let the thread detect that itself when it starts running jlong size = java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); // Allocate the C++ Thread structure and create the native thread. The // stack size retrieved from java is signed, but the constructor takes // size_t (an unsigned type), so avoid passing negative values which would // result in really large stacks. size_t sz = size > 0 ? (size_t) size : 0; native_thread = new JavaThread(&thread_entry, sz); ... if (native_thread->osthread() == NULL) { ... THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "unable to create new native thread"); } Thread::start(native_thread); JVM_END

从上面代码里首先要大家关注下最后的那个if判断if (native_thread->osthread() == NULL) ,如果osthread为空,那将会抛出大家比较熟悉的unable to create new native thread OOM异常,因此osthread为空非常关键,后面会看到什么情况下osthread会为空

另外大家应该注意到了native_thread = new JavaThread(&thread_entry, sz),在这里才会真正创建一个线程

 
JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) : Thread() #ifndef SERIALGC , _satb_mark_queue(&_satb_mark_queue_set), _dirty_card_queue(&_dirty_card_queue_set) #endif // !SERIALGC { if (TraceThreadEvents) { tty->print_cr("creating thread %p", this); } initialize(); _jni_attach_state = _not_attaching_via_jni; set_entry_point(entry_point); // Create the native thread itself. // %note runtime_23  os::ThreadTyp
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xuanwo007/article/details/107033180

智能推荐

Android studio如何导入Eclispe项目以及Eclispe如何导入Android项目_eclispe和android studio文件之间怎么转化-程序员宅基地

文章浏览阅读2.1k次。Android studio如何导入Eclispe项目直接导入,选择 Import project (Eclipse ADT, Gradle, etc.) 一路next就可以了。Eclispe如何导入Android studio项目不能直接导入,手工改。(以下Android studio简称 as)在eclipse 上新建一个空的项目;点击 android studio 中的android 视_eclispe和android studio文件之间怎么转化

android 设置TextView水平滚动和解决首行缩进问题_手机浏览器内文章段落首行不缩进-程序员宅基地

文章浏览阅读68次。android 设置TextView水平滚动和解决首行缩进问题_手机浏览器内文章段落首行不缩进

MySQL基础之表的管理-程序员宅基地

文章浏览阅读119次。添加和删除字段操作添加字段alter table tbl_name add 字段名称 字段属性 [完整性约束条件] [first|after 字段名称之后];删除字段alter table tbl_name drop 字段名称;测试create table if not exists user1( id int unsigned auto_increment key);--..._mysql基础之表的管理

栅格数据赋值编程C语言,使用Rasterio读取栅格数据的实例讲解-程序员宅基地

文章浏览阅读458次。Rasterio简介有没有觉得用GDAL的Python绑定书写的代码很不Pythonic,强迫症的你可能有些忍受不了。不过,没关系,MapBox旗下的开源库Rasterio帮我们解决了这个痛点。Rasterio是基于GDAL库二次封装的更加符合Python风格的主要用于空间栅格数据处理的Python库。Rasterio中栅格数据模型基本和GDAL类似,需要注意的是:在Rasterio 1.0以后,..._c语言栅格数据读取与基本操作

如何用python画一条蟒蛇_Python之绘制蟒蛇-程序员宅基地

文章浏览阅读4.1k次,点赞3次,收藏6次。1、turtle库是python常用的绘制图像的库,根据一组函数的指令决定轨迹图形。2、def用于定义函数,def所定义的函数在程序中未经调用不能直接执行,需要通过函数名调用才能执行。3、turtle.setup(宽度,高度,左上角横坐标,左上角纵坐标)——这个函数用于创建一个图形窗口。4、turtle.pensize(size)——表示运行轨迹的宽度,size单位为像素。5、turtle.pen..._python蟒蛇绘制中rad,angle,len,neckrad

XML解析_<?xml version="1.1"?>-程序员宅基地

文章浏览阅读456次。1. XML总结1.1. XML简介XML : 可扩展的标记语言。(和HTML非常类似的) - 可扩展的。 - 自定义的标签。与HTML区别: XML传输数据,HTML是显示数据。XML的版本: XML1.0(几乎都使用该版本) XML1.1(不向下兼容)做什么用?=>描述有关系的数据应用 1. 作为配置文件。 2. 可以在系统与系统之间进行数据的传输。 * webserivice_

随便推点

C语言中字符串用strcmp和==比较的问题_字符串可以用==比较吗-程序员宅基地

文章浏览阅读6.1k次,点赞8次,收藏47次。文章目录导论正文strcmp()函数实例1.字符串比较2.字符串变量比较3.字符串数组比较结论导论在判断两个字符串的内容是否相等的时候,如果使用==,当两个字符串不是指向内存中同一地址时,那么即使这两个字符串内容一样,但是用==比较出来的结果也是 false。所以两个字符串在比较内容是否相等的时候一定要使用strcmp()。正文strcmp()函数为了便于大家的阅读和理解,在这里先简单的介绍下strcmp()函数使用格式:#include<string.h>int strcmp_字符串可以用==比较吗

R语言文本特征工程:词袋模型-程序员宅基地

文章浏览阅读1.4k次。作者:黄天元,复旦大学博士在读,目前研究涉及文本挖掘、社交网络分析和机器学习等。希望与大家分享学习经验,推广并加深R语言在业界的应用。邮箱:huang.tian-yuan..._词袋法 文本相似度 r语言

android后台进程常驻,android 后台常驻,不会被kill-程序员宅基地

文章浏览阅读2.5k次。第一步:import android.app.Notification;import android.app.PendingIntent;import android.app.Service;import android.content.Context;import android.content.Intent;import android.media.MediaPlayer;import and..._安卓应用常驻通知 后是不是不会被杀死

贝叶斯线性回归文章汇总_贝叶斯回归分析和偏最小二乘回归分析-程序员宅基地

文章浏览阅读2.3k次。一、常规线性回归及其求解方法核心提炼1、普通最小二乘法(OLS)的解析解可以用 Gaussian 分布以及极大似然估计解释;2、Ridge 回归可以用 Gaussian 分布和最大后验估计解释 ;3、LASSO 回归可以用 Laplace 分布和最大后验估计解释。二、贝叶斯线性回归定义贝叶斯线性回归(Bayesian linear r..._贝叶斯回归分析和偏最小二乘回归分析

C数据结构:树和森林存储方式与遍历方式_c语言输入并存储一个森林-程序员宅基地

文章浏览阅读1.4k次,点赞5次,收藏15次。树的定义:只有一个根节点,但是分支可以没有规律,也就是说不像二叉树那样每个结点最多生出两个分支。而且树和接下去学习的图都有一个共同的特点就是套娃,无限套娃。树的存储结构方式都会用到数组顺序存储结构,数组是核心,数组结合链式的也有。至于为什么树要用到数组比较多,我认为是数组有一个很好的点就是他的位置可以很容易且快速的找到并访问,但是链式就不具有该优点,因为链式是一条绳子上的蚂蚱,必须一个一个的找。很显然就像名字说的那样,用该结点的双亲结点位置来表示当前的结点。双亲表示法就比如:让孩子记住自己父母的电话一_c语言输入并存储一个森林

位运算符——&0xFF的运算与讲解_代码对&0xff-程序员宅基地

文章浏览阅读1w次,点赞6次,收藏51次。区分 &,丨,^的运算规则 & (按位与运算符)表示:两个操作数中位都为1,结果为1如果两个操作中位一个1另一个0 ,结果为0即运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;例如:1010 & 1110= 1010|(按位或运算符)表示:两个操作中位只有一个为1,结果就等与1即运算规则:0|0=0; ..._代码对&0xff

推荐文章

热门文章

相关标签