Java JVM中的堆栈/堆

Java JVM中的堆栈/堆,java,c++,memory-management,jvm,Java,C++,Memory Management,Jvm,我来自C/C++背景,其中进程内存分为: 每线程堆栈 堆 指示 资料 我试图理解JVM是如何工作的,我查看了不同的资源,我发现JVM内存分为堆和堆栈,以及其他一些东西 我想把我的想法总结一下,当我阅读JVM中的堆和堆栈时,我们是在谈论堆栈和堆的概念吗?并且整个JVM的实际内存驻留在堆上(这里我指的是堆的C++概念)? 我想把我的想法总结一下,当我阅读JVM中的堆和堆栈时,我们是在谈论堆栈和堆的概念吗 是的,一般来说就是这样。每个线程都有自己的每线程堆栈,用于在堆栈帧中存储局部变量(对应于方法

我来自C/C++背景,其中进程内存分为:

  • 每线程堆栈
  • 指示
  • 资料
我试图理解JVM是如何工作的,我查看了不同的资源,我发现JVM内存分为堆和堆栈,以及其他一些东西

我想把我的想法总结一下,当我阅读JVM中的堆和堆栈时,我们是在谈论堆栈和堆的概念吗?并且整个JVM的实际内存驻留在堆上(这里我指的是堆的C++概念)? 我想把我的想法总结一下,当我阅读JVM中的堆和堆栈时,我们是在谈论堆栈和堆的概念吗

是的,一般来说就是这样。每个线程都有自己的每线程堆栈,用于在堆栈帧中存储局部变量(对应于方法调用)。堆栈不需要位于操作系统级别上与每线程堆栈相关的位置。如果堆栈试图增长超过
-Xss
指定的大小或实现设置的默认值,将抛出
堆栈溢出错误

堆栈可以存在于C/C++堆内存中,不需要是连续的():

每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与线程同时创建。Java虚拟机堆栈存储帧(§2.6)。Java虚拟机堆栈类似于传统语言(如C)的堆栈:它保存局部变量和部分结果,并在方法调用和返回中发挥作用。由于Java虚拟机堆栈除了用于推送和弹出帧之外从不直接操作,因此帧可能是堆分配的。Java虚拟机堆栈的内存不需要是连续的

Java堆是一种存储对象的方法,包括当对象不再可以通过强引用访问时自动垃圾收集。它在JVM上运行的所有线程之间共享

Java虚拟机有一个在所有Java虚拟机线程之间共享的堆。堆是运行时数据区域,所有类实例和数组的内存都是从该区域分配的

堆是在虚拟机启动时创建的。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象永远不会显式解除分配。Java虚拟机不采用特定类型的自动存储管理系统,可以根据实施者的系统需求选择存储管理技术。堆可以是固定大小的,也可以根据计算需要进行扩展,如果不需要更大的堆,则可以收缩堆。堆的内存不需要是连续的

通过简单地调用构造函数(例如,
HashMap foo=new HashMap()
),JVM将在堆上为此对象分配必要的内存(如果不可能,则抛出OutOfMemoryError)。还需要注意的是,对象永远不会存在于堆栈上——只有对它们的引用才会存在。此外,非基本字段也始终包含对对象的引用


在一些JVM上,通过
sun.misc.Unsafe
,一些分配直接缓冲区的NIO类,以及通过使用JNI,也可以从堆外分配内存。这个内存不是JVM堆的一部分,不进行自动垃圾回收(意思是它需要通过代码,例如代码>删除>代码>发布,但是它可能是堆内存的一部分,因为C++可以引用它。

谢谢你的回答。你能解释线程(java堆边)和本地线程是如何工作的吗?(本机堆端)交互?如果线程T1初始化
int a=5
你是说这不会映射到本机线程堆栈吗?为什么?为什么不?如果是,怎么做?@Kam
int a=5
将是堆栈框架的一部分,不必在本机线程堆栈中,因为堆栈框架通常不需要位于本机线程堆栈上。本机线程堆栈线程堆栈将包含解释字节码的本机代码中的局部变量。通常,Java线程以1:1的比例映射到OS线程,但也可能有所谓的线程,这些线程在当今非嵌入式Java上几乎不存在。啊,我明白了,也许我误解了每个Java线程都映射到本机线程的读数thread.谢谢!@Kam Java线程不需要映射到本机线程,但在大多数平台上,它们通常是1:1映射的,因为它们获得了提供给本机线程的某些本机并发功能的好处。本地堆栈也映射了吗?JVM仍然是在操作系统中运行的C程序。唯一的区别是JVM有一个托管堆,这是一个由JVM在C堆中管理的连续区域。线程堆栈仍然是堆栈,代码区域仍然是相同的。等等。