如果我将Tomcat线程池从N增加到N + 1个线程,需要多少额外内存?
当然,我的应用程序可能会对一些额外的内存负责,但让我们忽略它,我只对Tomcat需要多少感兴趣。
我想我可以自己运行一些测试并进行测量,但我希望有人已经这样做并且可以分享或指向结果。
答案 0 :(得分:3)
消耗的额外物理内存实际上根本没有。除非线程正常工作,否则操作系统不会浪费物理内存来保存其堆栈或相关结构。 (当然,它可能会消耗某些物理内存,因为它会创建初始堆栈。但如果线程没有运行,那可以并且将会被分页,而不会损害性能。 )
但是,线程的堆栈将消耗虚拟内存。您可以调整线程的最大堆栈大小,它是控制虚拟内存消耗量的最大堆栈大小。如果线程就在那里,它实际上是免费的。它计入虚拟内存限制,即使它不消耗真正有限的资源。
如果由于线程堆栈中的虚拟内存不足而遇到错误,可能最好的选择是增加虚拟内存限制。虚拟内存限制的目的是间接限制物理内存的使用 - 物理内存使用不会超过虚拟内存使用。但是如果你使用编程模式(比如许多线程)消耗虚拟内存而没有相应地使用物理内存,那么限制只会在它们不应该启动时启动。
当然,32位进程基本上限于2GB,3GB或4GB的虚拟内存(取决于平台)。因此,您可能别无选择,只能减少最大线程堆栈大小。 (一个线程立即消耗虚拟内存等于其最大堆栈大小,因为即使它从未使用过,也必须保留地址空间。)
减少最大线程堆栈大小也是一种选择。但这是妥协。较大的最大值可防止线程在其生命周期内需要大量堆栈时引发异常。消耗的唯一资源是地址空间,通常很便宜。但是,你可以强加给程序的唯一实际限制,就是防止它在物理内存上运行不足并且性能不佳,就是限制虚拟内存。所以你真正想要的旋钮不存在。
答案 1 :(得分:1)
我相信主内存使用量将是每个线程分配的堆栈空间。这可以通过-Xss
在命令行上控制答案 2 :(得分:0)
根据我所见,一个新的空闲线程将占用大约20KB-50KB的内存。
从那里开始,它可以根据堆栈深度(嵌套方法调用)以及参数和局部变量的数量(方法参数和局部变量中的所有原语和指针添加到堆栈中)的数量增长。被放在堆上)。
工作负载(线程正在工作时)将增加一些内存使用量,然后可以在请求完成时将其清除。但是,您不能将此归因于新线程,因为工作量必须由一个线程或另一个线程来选择。
长话短说:另一个线程将增加大约0.05 MB的内存使用。
注1: 似乎每个进程的线程数限制。因此,Linux实现可能允许单个JVM创建最多1000或2000个线程。
因此,您必须确保应用程序中的所有线程池加起来少于2000个线程。否则,当超出该限制时,JVM可能会突然崩溃。
注2: JVM NMT错误地报告了Java 8提交的内存,从而自动将其设置为保留内存。请参阅:https://bugs.openjdk.java.net/browse/JDK-8191369