代码之家  ›  专栏  ›  技术社区  ›  djangofan

为什么要减少Java JVM线程堆栈的大小?

  •  12
  • djangofan  · 技术社区  · 15 年前

    我在读一本 article 在处理爪哇(和JBoSE平台)内存不足的错误情况时,我看到了这个建议来减少线程堆栈的大小。

    减小线程堆栈的大小对最大内存错误情况有何帮助?

    4 回复  |  直到 12 年前
        1
  •  9
  •   RichieHindle    15 年前

    当Java创建一个新线程时,它预先为该线程的堆栈分配一个固定大小的内存块。通过减小内存块的大小,可以避免内存耗尽,特别是如果有很多线程,内存节省是堆栈大小乘以线程数的减少。

    这样做的缺点是增加了堆栈溢出错误的几率。

    请注意,线程堆栈是在jvm堆之外创建的,因此即使堆中有足够的可用内存,也可能由于内存不足(或者正如tom hawtin正确指出的那样,地址空间不足)而无法创建线程堆栈。

        2
  •  4
  •   Tom Hawtin - tackline    15 年前

    如果地址空间耗尽,则32位JVM上存在问题。减少最大堆栈大小通常不会减少实际分配的内存量。考虑8k线程,256kb预留给1k2mb的堆栈,这是31位地址空间(2gb)。

    这个问题在64位jvm中几乎消失了(尽管实际的内存量会增加一点,因为引用是原来的两倍大)。或者,使用非阻塞api可以消除对相当多线程的需求。

        3
  •  2
  •   Cheeso    15 年前

    一个进程中有n个线程,为每个线程堆栈分配m字节的内存。为堆栈使用分配的总内存为n x m。

    您可以通过减少线程数(n)或减少为每个线程分配的内存(m)来减少堆栈消耗的总内存。


    通常一个线程不会使用所有堆栈。它是预先分配的“以防”以后需要它,但是如果线程不使用深层调用路径,或者不使用递归,它可能不需要代表它分配的所有堆栈空间。

    找到最佳堆栈大小可能是一门艺术。

        4
  •  2
  •   luis.espinal    15 年前

    在尝试更改线程堆栈大小之前,我会尝试其他事情(例如更改幸存者比率或为类定义分配的空间大小)。很难纠正,因此很容易出现堆栈溢出错误(这与内存不足错误一样致命)。


    即使经过仔细的检查,我也没能把这个弄对。但话说回来,我可能从未遇到过可以通过更改线程堆栈大小来优化的web应用程序/容器组合。我有更好的(非致命的)结果修改幸存者比率。但那是 我的工作经验 . 在不同的工作场所和应用中,YMMV。