Tomcat线程占用多少内存



如果我将Tomcat线程池从N个线程增加到N+1个线程,将需要多少额外的内存?

当然,我的应用程序可能会占用一些额外的内存,但我们忽略这一点,我只是对Tomcat需要多少内存感兴趣。

我想我可以做一些测试并自己测量,但我希望有人已经做了,可以分享或指出结果。

消耗的额外物理内存实际上根本没有。除非线程工作,否则操作系统不会浪费物理内存来保存堆栈或相关结构。(当然,它可能会消耗一些物理内存,因为它会创建初始堆栈。但如果线程不运行,这些内存可以而且将被调出,不会对性能造成损害。)

但是,线程的堆栈将消耗虚拟内存。您可以调整线程的最大堆栈大小,而最大堆栈大小控制着虚拟内存的消耗量。如果线程只是停留在那里,那么它实际上是免费的。即使它不消耗实际的、有限的资源,它也会计入虚拟内存限制。

如果您遇到由于线程堆栈中的虚拟内存不足而导致的错误,那么最好的选择可能是增加虚拟内存限制。虚拟内存限制的目的是间接限制物理内存的使用——物理内存使用量不会超过虚拟内存使用量。但是,如果你使用的编程模式(比如很多线程)消耗虚拟内存,而没有相应地使用物理内存,那么限制就会在不应该使用的时候出现。

当然,32位进程从根本上被限制为2GB、3GB或4GB的虚拟内存(取决于平台)。因此,您可能别无选择,只能减小线程堆栈的最大大小。(线程立即消耗与其最大堆栈大小相等的虚拟内存,因为即使从未使用过地址空间,也必须保留地址空间。)

减少线程堆栈的最大大小也是一种选择。不过,这是一种妥协。如果线程在其生存期内需要大量堆栈,则较大的最大值可防止线程引发异常。唯一消耗的资源是地址空间,这通常很便宜。但是,为了防止程序的物理内存不足和性能不佳,你可以对程序施加的唯一实际限制是限制虚拟内存。所以你真正想要的旋钮并不存在。

我相信主要内存使用量将是为每个线程分配的堆栈空间。这可以在命令行上通过-Xss 进行控制

根据我所看到的,一个新的空闲线程将占用大约20KB-50KB的内存。

从那里开始,它可以根据堆栈深度(嵌套的方法调用)、参数和局部变量的数量(方法参数和局部参数中的所有基元和指针都会添加到堆栈中。而对象本身则放在堆上)来运行。

工作负载(当线程工作时)会增加一些内存使用量,然后在请求完成时就会被清除。但是,您不能将其归因于新线程,因为工作负载必须由一个或另一个线程选择。

长话短说:一个额外的线程将增加大约0.05MB的内存使用量

注1:每个进程的线程数似乎有一个限制。因此,linux实现可能允许单个JVM创建最多1000或2000个线程。

因此,您必须确保应用程序中的所有线程池加起来少于2000个线程。否则,当超出该限制时,JVM可能会突然崩溃。

注2:JVM NMT错误地报告Java 8提交的内存,自动将其设置为保留内存。参考:https://bugs.openjdk.java.net/browse/JDK-8191369

最新更新