我使用jvm参数-Xmx1024m
在我的机器和客户机器上运行以下程序。
int i=0;
while(true)
{
new Thread().start();
i++;
}
两台计算机都有windows 7
和jdk 7 32bits
。
在我的机器上,当我在3M附近时,我终止了这个过程。在客户的机器上,当i大约8K时,程序抛出OutOfMemoryError: unable to create new native Thread
。
我用jvm参数-Xmx24m
重试了实验。在这种情况下,当i大约24K时,客户机器上的程序会抛出相同的错误。如果我使用-Xss
将线程的堆栈跟踪减少到128K,那么也会有一个小的增量。
当线程终止时,客户的机器似乎没有释放线程的堆栈。
有没有人遇到过这个问题?有任何想法吗?
答案 0 :(得分:5)
您依赖于线程启动速度和随后死亡速度的细节。在一台机器上,线程生成过程超出了线程死亡过程,而在另一台机器上则发生了其他情况。您的计数器仅跟踪创建的线程总数,而不是任何时间点存在的线程净数。
要点:您的测试代码无助于证明有关运行时的任何重要信息。
答案 1 :(得分:1)
OutOfMemoryError: unable to create new native Thread
通常意味着您创建了比操作系统允许的更多的线程,不一定是您的线程堆栈空间不足。我会在每次创建后设置yield / sleep以允许操作系统赶上。
答案 2 :(得分:1)
当线程终止时,客户的机器似乎没有释放线程的堆栈。
可能会也可能不会。这取决于线程何时实际超出范围以及何时运行GC。此外,JVM可能不一定决定立即获取线程堆栈内存,因为它可能希望尝试重用线程而不是通过将其释放到JVM的另一部分来分段核心。线程的堆栈空间实际上很可能保留给线程使用,所以这更多是关于并发活动(或休眠)线程并重用它们而不是释放内存。
如果您要启动这么多线程,我建议使用固定数量的线程ExecutorService
,这样您就可以更好地控制启动的线程的精确数量。否则,你就是JVM和GC的心血来潮。