Java(JVM)如何为每个线程分配堆栈 [英] How does Java (JVM) allocate stack for each thread

查看:458
本文介绍了Java(JVM)如何为每个线程分配堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java应用程序启动时,所有线程都有一个堆。每个线程都有自己的堆栈。



启动Java应用程序时,我们使用JVM选项 -Xms -Xmx 控制堆的大小, -Xss 控制堆栈大小。



我的理解是,正在创建的堆成为JVM的托管内存,所有正在创建的对象都放在那里。



但堆栈创建如何工作? Java是否在创建每个线程时为其创建堆栈?如果是这样,那么堆栈究竟在哪里?它当然不在托管堆中。



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

解决方案

有一些关于线程堆栈的事情< a href =http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.2\"rel =noreferrer> Java规范告诉我们。除其他外:




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


  • 因为除了推送和弹出帧之外,永远不会直接操作Java虚拟机堆栈,因此可以对堆进行堆分配。 Java虚拟机堆栈的内存不需要是连续的。


  • 规范允许Java虚拟机堆栈具有固定大小或动态扩展和计算所要求的合同。




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




  • HotSpot中线程的最小堆栈大小似乎是固定的。这就是前面提到的 -Xss 选项。






    现在回答你的一些问题:


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


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


    Java在创建每个线程时是否为其创建堆栈?


    如前所述,每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与之同时创建线程。 (来源)


    如果是这样,那么堆栈究竟在哪里?它肯定不在托管堆中。


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


    JVM是否从本机内存创建堆栈或是否预先分配了一部分内存堆栈的托管内存区域?


    堆栈是JVM管理的,因为Java规范规定了它必须如何表现: Java虚拟机堆栈存储帧(第2.6节)。 Java虚拟机堆栈类似于传统语言的堆栈。一个例外是用于 native 方法的Native Method堆栈。有关详细信息,请参阅规范


    A Java application starts up with one heap for all threads. Each thread has its own stack.

    When a Java application is started, we use the JVM option -Xms and -Xmx to control the size of heap and -Xss to control the stack size.

    My understanding is that the heap being created becomes a "managed" memory of JVM and all the object being created are placed there.

    But how does the stack creation work? Does Java create a stack for each thread when it is created? If so, where exactly the stack is on the memory? It is certainly not in the "managed" heap.

    Does JVM create stack from native memory or does it pre-allocate a section of managed memory area for stack? If so, how does JVM know how may threads will be created?

    解决方案

    There are a few things about thread stacks that the Java specification tells us. Among other things:

    • Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread.

    • Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.

    • Specification permits Java Virtual Machine stacks either to be of a fixed size or to dynamically expand and contract as required by the computation.

    Now, if we focus on JVM implementations such as HotSpot, we can get some more information. Here are a few facts I've collected from different sources:

    • The minimum stack size in HotSpot for a thread seems to be fixed. This is what the aforementioned -Xss option is for. (Source)

    In Java SE 6, the default on Sparc is 512k in the 32-bit VM, and 1024k in the 64-bit VM. ... You can reduce your stack size by running with the -Xss option. ... 64k is the least amount of stack space allowed per thread.

    • JRockit allocates memory separate from the heap where stacks are located. (Source)

    Note that the JVM uses more memory than just the heap. For example Java methods, thread stacks and native handles are allocated in memory separate from the heap, as well as JVM internal data structures.

    • There is a direct mapping between a Java Thread and a native OS Thread in HotSpot. (Source).

    • But the Java thread stack in HotSpot is software managed, it is not an OS native thread stack. (Source)

    It uses a separate software stack to pass Java arguments, while the native C stack is used by the VM itself. A number of JVM internal variables, such as the program counter or the stack pointer for a Java thread, are stored in C variables, which are not guaranteed to be always kept in the hardware registers. Management of these software interpreter structures consumes a considerable share of total execution time.

    • JVM also utilizes the same Java thread stack for the native methods and JVM runtime calls (e.g. class loading). (Source).

    • Interestingly, even allocated objects may be sometimes located on stack instead on heap as a performance optimization. (Source)

    JVMs can use a technique called escape analysis, by which they can tell that certain objects remain confined to a single thread for their entire lifetime, and that lifetime is bounded by the lifetime of a given stack frame. Such objects can be safely allocated on the stack instead of the heap.

    And because an image is worth a thousand words, here is one from


    Now answering some of your questions:

    How does JVM knows how may threads will be created?

    It doesn't. Can be easily proved by contradiction by creating a variable number of threads. It does make some assumptions about the maximum number of threads and stack size of each thread. That's why you may run out of memory (not meaning heap memory!) if you allocate too many threads.

    Does Java create a stack for each thread when it is created?

    As mentioned earlier, each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. (Source).

    If so, where exactly the stack is on the memory? It is certainly not in the "managed" heap.

    As stated above, Java specification allows stack memory to be stored on heap, technically speaking. But at least JRockit JVM uses a different part of memory.

    Does JVM create stack from native memory or does it pre-allocate a section of managed memory area for stack?

    The stack is JVM managed because the Java specification prescribes how it must behave: A Java Virtual Machine stack stores frames (§2.6). A Java Virtual Machine stack is analogous to the stack of a conventional language. One exception are Native Method stacks used for native methods. More about this again in the specification.

    这篇关于Java(JVM)如何为每个线程分配堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆