【问题标题】:Java thread stack memory occupationJava线程栈内存占用
【发布时间】:2014-10-27 10:34:19
【问题描述】:

在我研究线程及其消耗的内存(线程堆栈)时,我决定 做一个简单的负载测试,看看线程数如何影响我计算机上的 RAM。

所以,对于我使用 Tomcat 的测试,在 settings.xml 中设置了最小和最大网络 将容器线程池设置为 200。之后我在将池设置为 2000 时做了同样的事情。 我很震惊,因为内存占用没有区别(正在检查 Windows 任务管理器),它几乎是一样的。所以我想也许那些线程有 处于运行状态,使用负载测试工具“轰炸”服务器,我已经管理 做一些重负载,大多数线程现在处于运行状态,但没有 200 到 2000 个线程之间的内存消耗变化。

所以我想知道这个线程的堆栈内存是什么,这些结果意味着什么 创建线程时未分配线程堆栈上的内存?我怎么会 能够模拟线程堆栈内存增长到 RAM 消耗差异的大小 在图表上被“肉眼”看到?

提前致谢!

【问题讨论】:

标签: java multithreading tomcat jvm


【解决方案1】:

线程栈分配在本机内存中(不在Java堆中),默认栈大小在256k到1M之间(取决于OS和JVM是32位还是64位),可以控制使用 -Xss JVM 选项。如果堆栈内存用完,则会出现“java.lang.OutOfMemoryError:无法创建新的本机线程”错误。

如果您想在操作系统级别跟踪 Windows 上的堆栈内存使用情况,请使用 VMMap 而不是任务管理器,因为它会显示堆栈内存。

如果你有一个带有 -XX:NativeMemoryTracking 和 jcmd 的最新 JDK,你也可以在 Java 中跟踪堆栈内存使用情况,详细信息是 here

我不知道你的测试有什么问题,我建议在你的代码中放一个 Thread.sleep 以确保所有线程都在运行。

【讨论】:

  • 好吧,经过更多测试后,我发现当你创建一个线程时,它不需要从本机内存中获取默认堆栈大小(从 256k 到 1M),它几乎不需要任何东西。因此,Xss JVM 参数大约是每个线程内存中的最大堆栈大小,而不是创建时的初始值。因此,从内存的角度来看,创建 10 或 1000 个线程并没有太大的区别。
  • 是的,在 vmmap 中你可以看到最初很大一部分线程堆栈内存只是“保留”的。无论如何,在现实生活中的应用程序中迟早需要分配整个堆栈内存,因此运行数千个线程仍然很重要。
  • 这是一篇很棒的文章,谢谢。此外,当您说在现实生活中的应用程序中迟早会分配整个堆栈内存时。好吧,我真的不知道如何。在线程堆栈中,您保存函数参数、方法调用、线程状态,这些都是轻量级的,以千字节为单位,所以我猜 10 或 1000 个线程之间的差异可能是几十 MB,这不是一个很大的改进吗?我错过了什么吗?
  • 好吧,不是整个最大堆栈,但比简单的测试程序要多得多。顺便说一句,在我的 4 GB RAM、64 位机器上,我刚刚设法启动了 50 000 个简单线程,但机器变得非常无响应 :) 无论如何,这并不重要,正如文章所说,如果你需要数千个线程,你的设计有缺陷,你应该重写它以使用异步 IO(在 Java NIO 中)
猜你喜欢
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2012-06-17
  • 1970-01-01
相关资源
最近更新 更多