正如我所知,Java 线程堆栈大小取决于 JVM 和操作系统架构,默认情况下(除非设置了 -Xss)在 256k 和 1m 之间变化。有没有一种方法或工具可以查看运行时所有当前正在运行的线程消耗的总堆栈大小,比如我可以使用 JDK 包中的 JVisualVM 查看堆大小或元空间大小?我知道这个值可以计算为线程堆栈大小 * 当前正在运行的线程数,但是在运行时监控这个值会很棒。
最佳答案
首先,默认堆栈大小是特定于平台的,但这并不意味着特定于平台的默认值会“变化”。我的记忆是,很长一段时间以来,默认值都没有改变(对于任何给定的“架构”)。 (可能从 Java 5 开始,如果不是更早的话。但不要引用我的话!)
您也不能使用默认值来准确确定实际分配了多少堆栈内存,因为:
-xss
覆盖平台默认值。命令行选项。正如你所指出的。 Thread
时,可以指定非默认堆栈大小。对象被创建。 Thread
时才实际分配。已启动。 (当 Thread
终止时,它会被释放。) 因此,如果您想测量实际分配的堆栈内存,则需要迭代所有线程并找到它们的实际堆栈大小。第一个应该相对简单:遍历
ThreadGroup
树。 (我认为你不能保证你会在遍历中看到所有线程,但这不重要。)第二个更困难,因为私有(private) Thread.stackSize
没有 getter字段...并且该字段仅记录应用程序提供给 Thread
的参数。构造函数。但是,由于典型应用程序只使用默认堆栈大小,因此计算线程数并乘以默认大小通常可以很好地估计总线程堆栈使用量。
也可以通过使用 Andrei Pangin 的 stackmem 的方法检查进程内存段来推断 JVM 分配的堆栈内存。脚本。 (注意这是 Linux 特有的,它依赖于 JVM 向操作系统请求单独的内存段以获取线程堆栈。)
另一方面,如果您想知道当前使用的堆栈空间量(不仅仅是分配的),则很难从应用程序中获得。如果您想通过代理获取它,我怀疑您需要先卡住 JVM。这对于定期监控是 Not Acceptable 。
但最重要的是,获取信息将是(至少!)非平凡的并且(IMO)可能不值得付出努力。通过查看线程数并乘以...
... it would be great to monitor this value in runtime.
不相信:-)
1 - 想知道使用了多少堆栈内存有两个可能的原因:您需要优化或好奇。在前一种情况下,知道使用了多少堆栈内存并不能直接告诉您应该使用多少。要确定后者,您实际上需要确定您是否有太多线程,或者这些线程的堆栈是否需要与当前一样大。 “原则上”或因为有人说这是“最佳实践”而减少堆栈内存使用可能会给您带来麻烦。
关于java - 实时监控 Java 中的总线程堆栈大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66093387/