00:01
同学们,我们继续,那么接下来我们看一个非常重要的错误啊,那。这两个比较重要,是现在外面经常考的,尤其是他。Unable to create new native thread。也就是不能够再创建更多新的本地线程了。把这句话翻译过来的意思就是说。你的程序不管属于微服务部署或者其他方式。布到我们的生产环境,比如说就是我们的Linux系统,那么呢。你现在创建线程的上限已经达到了,不能再创建更多了,报出这么一个错,可以这么讲,这个错,现在经常考大厂,为啥?三个字,高并发。因为高并发,你需要创建多线程,但是你在一个系统里面能够创建多少线程数,它是有一定的上限的,如果超过这个上限,将会报这么一个错误。
01:00
这个错误可以这么讲,如果没有生产环境的实验过,一般的人是答不出来的,你基本上你只要能答得出,比方说你的产,第一次你印象深刻的故障,第一次你有意义的故障,你收获了什么,你学习到了什么?那么这个问题我个人认为是一个非常好的案例。那么呢,这个问题呢,当年杨哥也是不知道在那个亚信在北京移动干了以后,那些生产上的环境啊,各种暴击卡,哎呀,填开填的也真的是天天996。谈判讲有时候都是在公司熬通宵,那么这些都是血泪的教训和加班熬夜换出来的真实的生产案例。好,那么它是个什么意思呢?首先。高并发请求服务器的时候,我们会发现这种错,准确的讲native的异常与对应的平台有关,那这是什么意思呢?那同学们哈,我们之前讲过一个问题哈,就是说呃,杨哥在讲勾UC的时候,我们呢说过一个情况,就是说呃,线程这个东西。
02:08
准确的讲跟语言关系不大,是跟操作系统有关系的。那么。这个时候哈,那假如说哈,我们现在呢,随便创建一个类,那么假设就叫T。干什么呢?同学们都干过这个?还是给大家复习一下吧。第。Start方法,我们讲过这个start最终什么情况,它掉的是一个叫START0这么一个方法,那么START0又是个什么方法?是不是我们的一个native方法?我们在讲勾UC的时候,详杨哥详细讲过,甚至还讲过一个经典的面试题,如果一个多线程是吧?那么现在。干嘛呢,比如说哈,他这个start两次以后,假如说当然不能这么写哈。
03:01
就是说这一块是不是已经是start了,如果再对应着这个线程再start一次会报什么异常,这个题是不是讲过,那么干脆呢,干嘛呢,再复习一下T等于这么一个。Start对吧,那么T一点。Start,然后再来一次。那么同学们。我们会看到是不是会报这么一个不合法的一个状态,为什么当时我们详细的读过代码干嘛,是不是只要它的start以后,本线程T1它的状态就已经变了,你再来一次啊,就会报这么一个异常,这是说过的,快快的复习一下。那么也就说什么。两次start好,OK,好,那么第二个START0,我们讲过这个是不是个native方法,所以说。导致我们这儿呢,就是说准确的讲这种。啊,是跟平台的应用有关,你把这个程序部署在Windows Linux,阿里云、华为云是不一样的,那么导致原因就是说你的应用创建了太多的线程,那么超过了,也就是一个应用进程创建了多个线程,注意这句话,一个应用进程里面创建了多个线程。
04:11
线程的上限是有有限限制的,你一个进程里面创建了多个线程,是不是把它撑爆了?那么超过了系统的承载极限,这是一种情况。第二个,你的服务器并不允许你的应用程序创建这么多的线程。Linux默认单个单个进程可以创建线程数是多少个1024个,那么你的应用创建的线程数量超过了这个数,就会把OM unable to create new native thread。不能够,也就是说你把这个程序布到我们的某个系统的上面,你当前的这个应用程序不再能够创建这么多的线程了,超过了我的极限。那么解决办法。降低你的应用程序,一个应用程序里面要创建的线程数量,坦白讲哈,一个进程里面你要创建这么多个也还是蛮多的了哈,你要分析一下是否真的需要创建那么多,如果不是。
05:09
改改代码,尽量不要创建这么多,当然你不要那个抬杠啊,他说好了,杨哥你说的是1024啊,我以后的程序踩着边边走,我就创建1023个。过分了,听懂了吧?啊,咱们不抬杠。第二个,对于有些应用,那么假设我确实要超过这个数呢?那痛快点,我想创建2000个,能不能要超过Linux系统默认的1024个线程的限制,我们就要去修改Linux服务器的配置,扩大Linux的默认限制,也就是说上线1024个。你要么超过他了,就会报这么一个异常,你要不想报这个异常,两种方法,第一个。降低你自己的创建数。第二个提升Linux的。线程承载上限速两种方法那么好。那么由于这个呢,是经常是在高并发的请求服务器的时候,这个错误现在考的非常多。
06:01
可以这么讲,如果面试官问你说你说说你做这个电商系统做这个,呃,你们的这些物流系统,银行系统等等,我们的这些练习系统的话,这些结业的这些最终的系统的话,你碰到过什么故障,那么这个时候杨哥呢,已经之前给大家讲过,那么这个时候干嘛再加深一下。在什么情况下出现高并发的请求服务器的时候好,那么我把这个程序呢步到我们的Linux的环境里面,让大家模拟真实的生产过程,那么这个程序呢,很好,写一个应用进程当中创建了多个线程,超过系统的承载极限就会报这个错。那么大家请看一下杨哥写的代码,因为这些代码呢都很简单哈,没有什么难的,我就不再多废话。注意。Four。In特I,我有没有写这个条件?故意的啊,这块是没有,重要的事情说三遍,For循环,杨哥故意使坏,故意下黑手,把这块给抠掉了。
07:02
那么这个时候干嘛?一加加说明它是不是没有一个跳出去的。环境不停的在这转,那么这个时候每进来一次是I,那么好,同学们请看我这个是一个主线程。进来以后for循环,那么言下之意一直在这转着,对吧?他没有说I小于多少的时候我再跳出,那么言下之意是不是符合我们的一个应用进程,May进程要创建多个线程,更加坑爹的是我使坏,我进来了以后我在这。你第一个线程I等于1START的时候,干嘛你就一永远在这停着,那么言下之意并没有退出去,就是只增不减,那么这样这样的话,这么干的话,这种坑爹的情况,那是不是一下子就会是一个main进程当中创建了那么多个什么线程,我这个I,我就要让大家看看我这个I加到多少。
08:00
会超过系统的承载极限,导致你报这么一个异常,那么Linux系统默认允许单个进程可以创建的线程数是多少?1024个,好,那么这块。我们的理论就给大家讲解到这儿,二话不说,真刀真枪看代码啊,我要用代码才能说得清楚,那么来,同学们,一般生产上你是不可能有资格用root用户的,我们现在用张三这个用户好,你。登录进去程序就是这个程序,也就是我idea里面的这个程序,好吧,那么呢,我直接呢,已经将它呢,提前课,刚才下课的时候节约时间哈,我们因为我们今天时间也要快到了,我节约时间我呢已经给他拷贝进了克啊。当前登录的用户啊,是张三好,那么。过了CD,那么。杨哥自己建的一个文件夹,那么这个时候那么听过我Linux的课的呢,大家都明白,那么现在我们这儿是不是有一个不能够创建更多的线程的这么一个Java类那么好。
09:03
由于呢,它是带了包明的,那么什么意思呢?哈,那么也就是说Java c-D点那么。UN,那么。干嘛编译,那编译通过了以后,我们大家看这。是不是有个come这么一个包啦,那么好,我们叫运行,运行的话是要带包名的,这么说同学们能不能跟上,那么这个包名怎么看呢?那么cat。Unable,那么过来,那么这个时候这个是我这大串苞米。那么我们运行的时候是不是要带包名啊,那么Java。我们呢?直接过来,那么Java是运行,那么前面的前缀包名是这么多,那么后面我们把这个干嘛呢?复制二,然后粘贴,那么来把这个点Java去掉,一定要注意是不是刚才编译通过包名叫看的硅谷这一串串串串串,然后我现在一运行。根据我们的线程,现在的代码,我是不是就不停的在这六线程啊,我们一个ma的进程里面,我这负循环故意抠掉了这块条件,再次强调我这儿不停的溜6666666,而且的话已经溜进来,就把着停在这儿不走了。
10:14
这个线这个这个内进程里面不停的,你有多个线程只增不减干嘛。超过系统承载极限,故意干坏事,要让大家看到这个错误,那么这个时候同学们请看,那么OK,我们在这块回到我们的Linux,那么现在杨哥在这一回车,那么大家请看。多少?940,哎,杨哥,不对呀,你不是说是到1024个吗?抱歉,它都会有一些理论数据,实际上有些句柄和线程,Linux系统它自身也需要占用掉一部分,所以说我们实际情况上到多少。普通的一个张三用户900多就挂了,那么为了保证干嘛你的上线安全,我认为用到2/3,也就是800个左右的线程已经是非常非常多了,很吃紧了系统。那么大家请看,又报了一种新的out of memory AR unable to create new native thread,不能够在什么创建更多的线程了,那么言下之意是不是完成了?
11:22
我们的这么一种东西,你现在丢出来的异常OK,那么就是我们的unable to create new native thread,那么为什么是native,刚才源码上已经给大家讲解过,好,那么同学们,那么这个时候就是我们的是吗?Native这么一个错,那现在大家请看这种错很麻烦哈,那你看我CTRLC。怎么着都退不出来,干嘛必须。就是说这个GVM可能需要强制的什么的terminated的给我干终结,那么二话不说碰上这种错怎么办?那么言下之见,我们切换回我们的。
12:03
假设现在我们模拟root用户登进来了,好,现在那么干什么呢?我们杠,然后竖线c Java程序。那么大家请看此时的时候,我们这是不是进程编号,你看左上角是不是有个叫张三18198这么一个进程编号,在运行着这么一个。com硅谷这么一个程序,那么OK。干嘛直接杀掉。那么。欧啦,那么18198,那么root册用户给他干掉,那么好切换回我们的什么张三这个用户,大家看什么情况以杀死,OK,那么言下之际,我们呢,就给大家呢介绍了我们的unable to create new native thread这么另外一种。OO。那么好,那么解决办法和我们的系统分析,我们再进一步的呢,来看我们的。首先啊,我们要查看,就是说。
13:02
这个张三这个用户默认最多可以创建多少线程,我们在哪看好?第一种我降低我程序的线程数,第二种假设我这个程序确确实实需要要创建这么多线程,我该怎么调整?那么这个时候呢,我们的解决方案就。过来了,那么这块非常重要,好,那么呢,我们来分两次讲,我先把故障给大家演示了,下一讲我们来说细节和具体更深入的分析。
我来说两句