Java(JVM)如何为每个线程分配堆栈
Java应用程序启动时,所有线程都有一个堆。每个线程都有自己的堆栈 当Java应用程序启动时,我们使用JVM选项Java(JVM)如何为每个线程分配堆栈,java,memory,jvm,Java,Memory,Jvm,Java应用程序启动时,所有线程都有一个堆。每个线程都有自己的堆栈 当Java应用程序启动时,我们使用JVM选项-Xms和-Xmx控制堆的大小,并使用-Xss控制堆栈大小 我的理解是,正在创建的堆成为JVM的“托管”内存,所有正在创建的对象都放在那里 但是堆栈创建是如何工作的呢?Java在创建每个线程时是否为其创建堆栈?如果是,堆栈在内存中的确切位置是什么?它肯定不在“托管”堆中 JVM是从本机内存创建堆栈,还是为堆栈预先分配一部分托管内存区域?如果是这样,JVM如何知道如何创建线程 JVM使用
-Xms
和-Xmx
控制堆的大小,并使用-Xss
控制堆栈大小
我的理解是,正在创建的堆成为JVM的“托管”内存,所有正在创建的对象都放在那里
但是堆栈创建是如何工作的呢?Java在创建每个线程时是否为其创建堆栈?如果是,堆栈在内存中的确切位置是什么?它肯定不在“托管”堆中
JVM是从本机内存创建堆栈,还是为堆栈预先分配一部分托管内存区域?如果是这样,JVM如何知道如何创建线程
JVM使用的内存不仅仅是堆。比如Java方法,
线程堆栈和本机句柄分别在内存中分配
堆以及JVM内部数据结构
因此,要回答您的问题:
Java在创建每个线程时是否为其创建堆栈
对
如果是,堆栈在内存中的确切位置是什么
在JVM分配的内存中,但不在堆上
如果是这样,JVM如何知道如何创建线程
没有
您可以创建任意数量的JVM,直到您的JVM内存达到最大值,并且
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
编辑:
上面提到的都是JVM,尽管我发现很难相信其他JVM在这些基本问题上会有不同。关于线程堆栈,有几件事可以告诉我们。除其他外:
- 每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与线程同时创建
- 由于Java虚拟机堆栈除了用于推送和弹出帧之外从不直接操作,因此帧可能是堆分配的。Java虚拟机堆栈的内存不需要是连续的
- 该规范允许Java虚拟机堆栈具有固定大小,或者根据计算需要动态扩展和收缩
- 热点中线程的最小堆栈大小似乎是固定的。这就是前面提到的
选项的用途。-Xss
- JRockit将内存与堆栈所在的堆分开分配李>
- HotSpot中的Java线程和本机OS线程之间存在直接映射
- 但是HotSpot中的Java线程堆栈是由软件管理的,它不是OS本机线程堆栈
- JVM还将相同的Java线程堆栈用于本机方法和JVM运行时调用(例如类加载)
- 有趣的是,作为性能优化,即使是分配的对象有时也可能位于堆栈上,而不是堆上
现在回答您的一些问题: JVM如何知道如何创建线程 没有。通过创建不同数量的线程,可以很容易地用矛盾来证明。它确实对线程的最大数量和每个线程的堆栈大小做了一些假设。这就是为什么如果分配太多线程,可能会耗尽内存(不是指堆内存!) Java在创建每个线程时是否为其创建堆栈 如前所述,每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与线程同时创建 如果是,堆栈在内存中的确切位置是什么?它肯定不在“托管”堆中 如上所述,从技术上讲,允许堆栈内存存储在堆上。但至少JRockit JVM使用了不同的内存部分 JVM是从本机内存创建堆栈,还是为堆栈预先分配一部分托管内存区域
堆栈是JVM管理的,因为Java规范规定了它的行为:Java虚拟机堆栈存储帧(§2.6)。Java虚拟机堆栈类似于传统语言的堆栈。一个例外是用于
本机
方法的本机方法堆栈。有关这方面的更多信息,请参见。此外,虽然这些都是很好的答案,但这是JVM的内部规范。上述任何一项都可能随时发生变化。它不应该,也不应该,不管JVM如何工作。让JVM决定如何最好地管理它的资源。是的,但这并不意味着找出它是如何管理它的