当线程终止时,jvm是否释放线程的堆栈

时间:2014-02-27 14:53:24

标签: java multithreading exception garbage-collection out-of-memory

我使用jvm参数-Xmx1024m在我的机器和客户机器上运行以下程序。

int i=0;
while(true)
{
  new Thread().start();
  i++;
}

两台计算机都有windows 7jdk 7 32bits

在我的机器上,当我在3M附近时,我终止了这个过程。在客户的机器上,当i大约8K时,程序抛出OutOfMemoryError: unable to create new native Thread

我用jvm参数-Xmx24m重试了实验。在这种情况下,当i大约24K时,客户机器上的程序会抛出相同的错误。如果我使用-Xss将线程的堆栈跟踪减少到128K,那么也会有一个小的增量。

当线程终止时,客户的机器似乎没有释放线程的堆栈。

有没有人遇到过这个问题?有任何想法吗?

3 个答案:

答案 0 :(得分:5)

您依赖于线程启动速度和随后死亡速度的细节。在一台机器上,线程生成过程超出了线程死亡过程,而在另一台机器上则发生了其他情况。您的计数器仅跟踪创建的线程总数,而不是任何时间点存在的线程净数。

要点:您的测试代码无助于证明有关运行时的任何重要信息。

答案 1 :(得分:1)

OutOfMemoryError: unable to create new native Thread

通常意味着您创建了比操作系统允许的更多的线程,不一定是您的线程堆栈空间不足。我会在每次创建后设置yield / sleep以允许操作系统赶上。

答案 2 :(得分:1)

  

当线程终止时,客户的机器似乎没有释放线程的堆栈。

可能会也可能不会。这取决于线程何时实际超出范围以及何时运行GC。此外,JVM可能不一定决定立即获取线程堆栈内存,因为它可能希望尝试重用线程而不是通过将其释放到JVM的另一部分来分段核心。线程的堆栈空间实际上很可能保留给线程使用,所以这更多是关于并发活动(或休眠)线程并重用它们而不是释放内存。

如果您要启动这么多线程,我建议使用固定数量的线程ExecutorService,这样您就可以更好地控制启动的线程的精确数量。否则,你就是JVM和GC的心血来潮。