好吧所以我对JVM的内存段有疑问, 我知道每个JVM都会选择实现这个有点不同但它是一个整体概念,应该在所有JVM中保持相同
在运行时期间不使用虚拟机执行的标准C / C ++程序在运行时有四个内存段, 代码/堆栈/堆/数据 所有这些内存段都是在运行时由操作系统自动分配的。
但是,当JVM执行Java编译的程序时,在运行时它有5个内存段
方法区/堆/ Java堆栈/ PC寄存器/本机堆栈
我的问题是,谁分配和管理那些内存段? 操作系统不知道正在运行的java程序,并认为它是作为计算机上的常规程序运行的JVM的一部分,JIT编译,Java堆栈使用,这些操作需要运行时内存分配,以及我是什么无法理解JVM是如何将内存划分为这些内存段的。 它绝对不是由操作系统完成的,那些内存段(例如java堆栈)必须是连续的才能工作,所以如果JVM程序只是使用诸如malloc之类的命令来获得最大的大小堆内存并将内存分成几段,我们没有连续记忆的承诺,如果有人可以帮我把这个直接记在脑子里,我会喜欢它,这一切都搞混了......
答案 0 :(得分:3)
当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之类的命令来接收堆内存的最大大小并将该内存划分为段,
堆被分为几代或G1多个内存块,但这仅供对象使用。
我们没有连续记忆的承诺
垃圾收集器通过复制它来对内存进行碎片整理,或者采取措施减少它以确保为您分配的任何对象提供足够的连续内存。
如果有人可以帮助我直截了当地表达这一点,那就会爱上它,它会混淆......
简而言之,JVM像任何其他程序一样运行,除非Java代码运行时它的对象被分配在内存的托管区域中。所有其他内存区域的行为与在C程序中的行为一样,因为JVM是一个C / C ++程序。