当前位置: 首页 > 知识库问答 >
问题:

Java(JVM)如何为每个线程分配堆栈

裴畅
2023-03-14

但是堆栈创建是如何工作的呢?Java是否在创建每个线程时为其创建堆栈?如果是,堆栈在内存上的具体位置?它当然不在“托管”堆中。

JVM是从本机内存创建堆栈还是为堆栈预先分配了一段托管内存区域?如果是,那么JVM如何知道如何创建线程呢?

共有1个答案

彭骏
2023-03-14

Java规范告诉我们关于线程堆栈的一些事情。除其他外:

>

  • 每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与线程同时创建。

    因为Java虚拟机堆栈除了推送和弹出帧之外从来不直接操作,所以帧可能是堆分配的。Java虚拟机堆栈的内存不需要是连续的。

    规范允许Java虚拟机堆栈具有固定的大小,或者根据计算的需要动态扩展和收缩。

    现在,如果我们专注于HotSpot等JVM实现,就可以获得更多的信息。以下是我从不同来源收集到的一些事实:

    • 线程在热点中的最小堆栈大小似乎是固定的。这就是前面提到的-xss选项的用途。(来源)
      null

    但是HotSpot中的Java线程堆栈是软件管理的,它不是一个OS本机线程堆栈。(资料来源)

    它使用一个单独的软件堆栈来传递Java参数,而本机C堆栈则由VM本身使用。许多JVM内部变量(如程序计数器或Java线程的堆栈指针)存储在C变量中,这些变量不能保证始终保存在硬件寄存器中。这些软件解释器结构的管理消耗了总执行时间的相当大一部分。

    >

  • JVM还将相同的Java线程堆栈用于本机方法和JVM运行时调用(例如,类加载)。(资料来源)。

    现在回答您的一些问题:

    JVM如何知道如何创建线程?

    它没有。可以通过创建一个可变数量的线程轻松地用矛盾来证明。它确实对每个线程的最大线程数和堆栈大小做了一些假设。这就是为什么您可能会耗尽内存(不是指堆内存!)如果您分配了太多的线程。

    如上所述,Java规范允许堆栈内存存储在堆上,从技术上讲。但至少JRockit JVM使用了不同的内存部分。

    JVM是从本机内存创建堆栈还是为堆栈预先分配了一段托管内存区域?

    堆栈由JVM管理,因为Java规范规定了它的行为方式:Java虚拟机堆栈存储帧(§2.6)。Java虚拟机堆栈类似于传统语言的堆栈。一个例外是用于Native方法的本机方法堆栈。关于这一点的更多信息,请参见规范。

  •  类似资料:
    • 我对所有这些异步/多线程lib和本地clojure功能感到迷茫。 我有一个Web服务,它调用外部API,转换它响应,然后回馈给客户端。现在是用Python编写的。我想让每个客户端在单独的线程中执行其请求,这样它们就不会等待彼此完成,或者服务器是异步的。不涉及繁重的计算,只需等待IO。 我原以为使用clojure会很容易,但是我忽略了一些东西...Aleph是异步服务器吧?然而,当我在请求处理程序中

    • 基于每个JVM的CPU核数创建线程与在多个JVM上运行的线程在CPU核数上创建线程数,条件是所有JVM运行在共享同一CPU的一个物理系统上有何不同?换句话说,一个并行运行8个线程的多线程Java程序vs在共享同一CPU的8个不同JVM上运行的同一多线程程序? 下面我给出了一些我发现的用线程实现并行处理的方法,但是我不能理解它们之间的本质区别? 方法一:线程周期性地查询数据库更改,并行地启动(长时间

    • 本文向大家介绍深入JVM剖析Java的线程堆栈,包括了深入JVM剖析Java的线程堆栈的使用技巧和注意事项,需要的朋友参考一下 在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因。在我看来线程堆栈分析技术是Java EE产品支持工程师所必须掌握的一门技术。在线程堆栈中存储的信息,通常远超出你的想象,我们可以在工作中善加利用这些信息。 我的目标是分享我过去十几年来在线程

    • 问题内容: 我想知道是否有人可以指出有关解释用提取的Java线程堆栈的信息。 我的情况是我在GlassFish v2.1.1上运行了一个Java EE 5应用程序,该应用程序定期挂起(每天至少挂2次-3次)。要使其再次运行,我必须终止Glassfish进程并重新启动域。 。应用程序通常会变得越来越慢,直到最终完全挂起。一旦挂起,我将无法获得线程堆栈。我已经能够获得一个线程堆栈,因为它变得越来越慢,

    • 我们的一个sap系统(PI ABAP JAVA stack)出现了性能问题。为机器配置的整个64GB都被占用了(还有8个内核)。每个人都在怀疑java部分,但我认为不同。 重启内存不足错误的java服务器节点。查看hprof文件,我发现当为服务器节点配置3GB(-Xms和Xmx)堆时,它们的大小只有1.2G(3个服务器节点的平均大小)。这一观察导致以下疑问。 我读到过,当Xms和Xmx设置为相同的

    • 我知道Java中内存分配的基本原理——应用程序占用的大部分内存都分配在堆上,堆由所有线程共享,因此没有线程拥有对象的概念,您无法轻松计算线程使用它拥有的所有对象占用了多少内存。 但我想知道是否有任何方法可以计算和汇总从特定线程触发的分配?内存分配发生在堆上,但它总是由想要创建对象的线程触发,所以我想知道是否可以以某种方式分析这种关系? 我的想法是,一个典型的Spring Boot应用程序将引导,从