Java 为什么没有获得堆栈实际大小的方法?

Java 为什么没有获得堆栈实际大小的方法?,java,stack,Java,Stack,我知道在运行时无法获得Java中线程的堆栈大小(请参阅) 例如,如果我们创建一个指定64*1024堆栈大小的线程,JVM可以自由地给我们一个具有任意堆栈大小的线程 然而,我相信,对于某些需要此类信息的应用程序,了解堆栈的实际大小是非常有用的 为什么我们没有一个方法来告诉我们堆栈使用的实际字节数 体系结构中是否存在某种限制,使得无法获取线程的实际字节数?堆栈上存储的唯一内容是基本类型和引用。对象总是在堆上创建的,因此将存储在堆栈上的数据类型是 byte、char、int、long、float、d

我知道在运行时无法获得Java中线程的堆栈大小(请参阅)

例如,如果我们创建一个指定64*1024堆栈大小的线程,JVM可以自由地给我们一个具有任意堆栈大小的线程


然而,我相信,对于某些需要此类信息的应用程序,了解堆栈的实际大小是非常有用的

为什么我们没有一个方法来告诉我们堆栈使用的实际字节数


体系结构中是否存在某种限制,使得无法获取线程的实际字节数?

堆栈上存储的唯一内容是基本类型和引用。对象总是在堆上创建的,因此将存储在堆栈上的数据类型是

  • byte、char、int、long、float、double类型的局部变量最长的是double,即8个字节
  • 对对象的引用在32位vm上为4字节,在64位vm上为8字节(可能更短,48位引用用于节省空间)
请注意,数组是对象类型,因此它们存储在堆上。此外,如果在类中有一个作为字段的基元,则该基元是对象的一部分,因此将存储在堆上

因此,除非有T台递归,否则很难耗尽线程的堆栈空间。我想这就是为什么Java设计人员不给您一种方法来找出堆栈大小的原因


不给出堆栈大小的另一个原因是,它将是一个实现细节,您无法真正处理它,在创建线程后无法更改线程堆栈的大小,也无法执行指针运算,因此了解堆栈大小的意义何在

“然而,我认为,对于某些需要此类信息的应用程序,了解堆栈的实际大小非常有用。”你有什么例子吗?@MarkByers,例如,web服务器或操作系统。为什么web服务器需要知道堆栈大小?这是一个应用程序的例子,这不是一个关于为什么知道这一点会有用的例子。@Bombe如果我们有关于实际堆栈大小的信息,就可以进行调优。例如,如果我想进行密集计算,可以根据堆栈的大小动态选择不同的算法。我是一个线程池,出生时我想创建30个线程,每个线程的堆栈大小为64Kb。但是,如果JVM忽略我的堆栈大小请求,并创建堆栈大小为1Mb的每个线程,那么我不希望创建30个线程。如果每个线程的堆栈大小为512Kb,我将创建15个线程。否则,如果每个线程的堆栈大小为1Mb,我将创建10个线程(以此类推)。但是,我无法查询堆栈大小,现在我只能假设@Pacier堆栈大小相对于堆大小非常小,因此拥有更多线程的问题不是单个线程的堆栈大小,而是每个线程使用的堆内存量。线程越多,可能需要的堆就越多。在你担心KB内存的情况下,运行你的应用程序的目标是什么类型的硬件?我是否误解了什么,因为线程本身并不占用任何堆内存。如果我有10个MyThreadPool实例,每个MyThreadPool有30个线程,每个线程有1Mb的堆栈大小,即总共300Mb的内存。另一方面,如果每个线程的堆栈大小为64Kb,则只需要18.75Mb内存。即使在高于平均水平的情况下,这也是一个巨大的差异computer@Pacerier我要指出的是,您运行的每个线程可能都在做一些事情,不管线程在做什么,它都会消耗堆空间和堆栈空间,我假设线程在正常的线程执行过程中消耗的堆空间将大于堆栈空间。因此,我的评论是,线程越多,可能需要的堆就越多。@Pacerier在您给出的示例中,有10个线程池,每个线程池30个线程,您有300个线程,这是很多线程,CPU和堆可能在堆栈用完之前就成了问题。为什么您如此关注堆栈大小占总内存使用量的百分比。还要记住,分配的内存和提交的内存之间是有区别的,因此即使JVM调用malloc()并请求1MB的堆栈,这意味着JVM可以安全地执行指针运算,操作系统也不会分配内存,直到JVM写入内存。