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