Memory JVM内存段分配

Memory JVM内存段分配,memory,garbage-collection,jvm,Memory,Garbage Collection,Jvm,好的,我有一个关于JVM内存段的问题, 我知道每个JVM都会选择实现这一点,但这是一个总体概念,在所有JVM中应该保持不变 一个不使用虚拟机在运行时执行的标准C/C++程序,在运行时有四个内存段, 代码/堆栈/堆/数据 所有这些内存段都由操作系统在运行时自动分配 然而,当JVM执行Java编译程序时,在运行时它有5个内存段 方法区域/堆/Java堆栈/PC寄存器/本机堆栈 我的问题是,谁分配和管理这些内存段? 操作系统不知道java程序在运行,认为它是JVM的一部分,在计算机上作为常规程序运行,

好的,我有一个关于JVM内存段的问题, 我知道每个JVM都会选择实现这一点,但这是一个总体概念,在所有JVM中应该保持不变

一个不使用虚拟机在运行时执行的标准C/C++程序,在运行时有四个内存段, 代码/堆栈/堆/数据 所有这些内存段都由操作系统在运行时自动分配

然而,当JVM执行Java编译程序时,在运行时它有5个内存段

方法区域/堆/Java堆栈/PC寄存器/本机堆栈

我的问题是,谁分配和管理这些内存段? 操作系统不知道java程序在运行,认为它是JVM的一部分,在计算机上作为常规程序运行,JIT编译,java堆栈使用,这些操作需要运行时内存分配,我不理解的是JVM如何将内存划分为这些内存段。
这肯定不是由操作系统完成的,这些内存段(例如java堆栈)必须是连续的才能工作,因此,如果JVM程序只是使用诸如malloc之类的命令来接收最大大小的堆内存并将该内存划分为多个段,那么我们无法保证连续内存,如果有人能帮我弄清楚这一点,我会很高兴的,这一切都搞混了…

当JVM启动时,它有成百上千的内存区域。例如,每个线程都有一个堆栈以及一个线程状态区域。每个共享库和jar都有一个内存映射。注意:Java 64位不像16位应用程序那样使用段

谁分配和管理这些内存段

所有内存映射/区域都由操作系统分配

操作系统不知道java程序正在运行,认为它是JVM的一部分,在计算机上作为常规程序运行

JVM作为常规程序运行,但是内存分配使用与普通程序相同的机制。唯一的区别是,在Java中,对象分配是由JVM管理的,但这是唯一以这种方式工作的区域

JIT编译、Java堆栈使用、

JIT编译发生在一个普通的OS线程中,每个Java堆栈都是一个普通的线程堆栈

这些操作需要运行时内存分配

它确实如此,并且在大多数情况下使用
malloc
free
map
unmap

我没有理解的是JVM是如何将内存划分为这些内存段的

没有。堆仅用于Java对象。例如,最大堆不是最大内存使用量,而是一次可以拥有的对象的最大数量

这肯定不是由操作系统完成的,这些内存段(例如java堆栈)必须是连续的才能工作

你是对的,它们需要在虚拟内存中保持连续,但操作系统做到了这一点。在Linux上,至少没有使用段,只有一个32位或64位内存区域

因此,如果JVM程序只是使用诸如malloc之类的命令来接收最大大小的堆内存,并将该内存分成若干段

堆被分为几代或多个内存块,但这仅适用于对象

我们没有关于连续内存的承诺

垃圾收集器要么通过复制内存来整理内存碎片,要么采取措施尝试减少内存碎片,以确保有足够的连续内存用于分配的任何对象

如果有人能帮我把这件事想清楚,我会很高兴的,这一切都搞混了


简言之,JVM与任何其他程序一样运行,除了Java代码运行时,它的对象被分配到内存的托管区域。所有其他内存区域的作用与C程序中的一样,因为JVM是一个C/C++程序。

回答得好,我也想写一个,但不确定如何精确地表达它。简而言之,你的最后一句话总结了我所说的:
所有其他内存区域的行为与C程序中的一样,因为JVM是C/C++程序。
首先,非常感谢你,这确实帮助我理解了很多!,但是我仍然不理解一件事,我在很多地方读到java堆栈不一定是用连续内存实现的线程堆栈,你能给我解释一下吗?@DrPrItay哪个“一件事”是吗?@DrPrItay我看不出你做了什么改变。@PeterLawrey ahh我的问题是我在很多地方读到java堆栈不一定是用连续内存实现的线程堆栈,像C/C++程序的常规堆栈应该是连续的,在java中我读到堆栈帧的实现略有不同