我来自C/C++背景,其中进程内存被划分为:
我试图理解JVM是如何工作的,我查看了不同的资源,我发现JVM内存也被划分为堆和堆栈,再加上很少的其他东西。
当我在JVM中阅读堆和堆栈时,我们谈论的是堆栈和堆的概念吗?而整个JVM的实际内存驻留在堆中(这里我指的是堆的C++概念)?
发布于 2016-04-29 20:01:37
当我在JVM中阅读堆和堆栈时,我们谈论的是堆栈和堆的概念吗?
是的,一般来说是这样的。每个线程都有自己的每个线程堆栈,用于在堆栈帧中存储局部变量(对应于方法调用)。堆栈不需要位于操作系统级别上与每个线程堆栈相关的位置。如果堆栈试图超过-Xss
指定的大小或实现设置的默认大小,则将引发StackOverflowError
。
堆栈可以存在于C/C++堆内存中,并且不需要连续(JVM规范v7):
每个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堆的一部分,也不需要进行自动垃圾收集(这意味着它需要通过诸如delete
这样的方式释放,但它可能是堆内存的一部分,因为C++可能会引用它。
https://stackoverflow.com/questions/36946455
复制相似问题