答:Java线程创建相关的几个小知识点问题

昨天问题收到的两个典型答复如下:
1. 一个线程占用1m的空间,一直循环下去将会导致内存空间不足,进而占用swap区域,因此报第一个错;第二个错是因为swap区域亦不足,导致ls等命令都无空间可运行。
2. xss是一个线程的分配空间。题目设置的1m 一共2w 4w个当然会报内存溢出。

这两个回答都不正确。
正确的答案和原因是:
1. 当用-Xss1m执行时,VIRT会占用20000M左右,RES会很少,原因是线程启动后,只是会去先占用相应的栈大小的地址空间,但不会真正去占用内存,只有在真正需要使用的时候才会去占用;如果是在32bit机器上执行,Java进程会直接crash,原因是32 bit的linux默认每个进程最多申请3G的地址空间;

2. 可能会出现java.lang.OutOfMemoryError:unable to create new native thread的原因不是因为内存被耗光,而是因为os对每个用户能创建的最多进程/线程数的限制,限制的个数是多少可以通过ulimit -u进行查看,当创建的线程个数超过了os的这个值的限制,也会抛出上面的异常;

3. 可能会出现Resource temporarily unavailable的原因同样不是内存被耗光,像linux 2.6.18/32等内核默认的kernel.pid_max的值为32768,意味着在单台机器上最多创建32768个线程,即使ulimit -u的值超过32768也没用,因此如果在未调过kernel.pid_max的机器上执行创建4w个线程的代码,就会出现Resource temporarily unavailable。

之前微博上的九州-姬野之前给我分享了一个cpu sy高的排查case,挺有意思的,这里有个类似的case,感兴趣的可以看看:
http://structureddata.org/2012/06/18/linux-6-transparent-huge-pages-and-hadoop-workloads/