我来自C / C ++背景,其中进程内存分为:
我试图理解JVM是如何工作的,我查看了不同的资源,我认为JVM内存分为堆和堆栈以及其他一些东西。
我想围绕这一点,当我在JVM中读取堆和堆栈时,我们是在讨论堆栈和堆的概念吗?并且整个JVM的实际内存驻留在堆上(这里我的意思是堆的C ++概念)?
答案 0 :(得分:1)
我想围绕这一点,当我在JVM中读取堆和堆栈时,我们是在讨论堆栈和堆的概念吗?
是的,总的来说就是这种情况。每个线程都有自己的每线程堆栈,用于在堆栈帧中存储局部变量(对应于方法调用)。堆栈不需要位于与OS级别的每线程堆栈相关的位置。如果堆栈尝试超出-Xss
指定的大小或实现设置的默认值,则会抛出StackOverflowError
。
堆栈可以存在于C / C ++堆内存中,不需要是连续的(JVM spec v7):
每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与线程同时创建。 Java虚拟机堆栈存储帧(第2.6节)。 Java虚拟机堆栈类似于传统语言的堆栈,例如C:它保存局部变量和部分结果,并在方法调用和返回中起作用。由于除了推送和弹出帧之外,永远不会直接操作Java虚拟机堆栈,因此可以对堆进行堆分配。 Java虚拟机堆栈的内存不需要是连续的。
Java堆是一种存储对象的方法,包括通过强引用无法再访问对象时的自动垃圾收集。它在JVM上运行的所有线程之间共享。
Java虚拟机具有在所有Java虚拟机线程之间共享的堆。堆是运行时数据区,从中分配所有类实例和数组的内存。
在虚拟机启动时创建堆。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象永远不会被显式释放。 Java虚拟机假设没有特定类型的自动存储管理系统,可以根据实现者的系统要求选择存储管理技术。堆可以具有固定大小,或者可以根据计算的需要进行扩展,并且如果不需要更大的堆,则可以收缩。堆的内存不需要是连续的。
通过简单地调用构造函数(例如HashMap foo = new HashMap()
),JVM将在堆上为此对象分配必需的内存(如果不可能则抛出OutOfMemoryError)。同样重要的是要注意对象永远不会存在于堆栈中 - 只有对它们的引用。此外,非原始字段也始终包含对对象的引用。
也可以通过sun.misc.Unsafe
在一些JVM上分配内存,一些分配直接缓冲区的NIO类,以及通过使用JNI。此内存不是JVM堆的一部分,并且不会进行自动垃圾收集(意味着它需要通过delete
等方式释放,但它可能是堆内存的一部分,因为C ++可能引用它