Java 堆外、本机堆、直接内存和本机内存之间有什么区别?

Java 堆外、本机堆、直接内存和本机内存之间有什么区别?,java,memory,jvm,Java,Memory,Jvm,最近,我在学习JVM内部结构时遇到了这些概念。我知道已经有很多关于他们个人的问题,但是我仍然不能理解他们之间的关系,或者仅仅是他们是什么 现在我这样描述他们: 本机内存表示正常JVM堆之外的内存区域,但仍在操作系统为JVM进程保留的总用户空间内存内(例如,在32位Windows上,默认为2GB)。JVM保留这个空间来存储一些内部数据,例如永久生成/方法区域等 直接内存表示通过java.nio.DirectByteBuffer使用本机内存 本机堆表示您通过不安全的方式使用本机内存。alloca

最近,我在学习JVM内部结构时遇到了这些概念。我知道已经有很多关于他们个人的问题,但是我仍然不能理解他们之间的关系,或者仅仅是他们是什么

现在我这样描述他们:

  • 本机内存表示正常JVM堆之外的内存区域,但仍在操作系统为JVM进程保留的总用户空间内存内(例如,在32位Windows上,默认为2GB)。JVM保留这个空间来存储一些内部数据,例如永久生成/方法区域等

  • 直接内存表示通过
    java.nio.DirectByteBuffer
    使用本机内存

  • 本机堆表示您通过
    不安全的方式使用本机内存。allocateMemory
    或在JNI代码中执行
    malloc

  • 堆外与本机内存相同

  • 还有一个问题,是否可以直接在JVM进程的总内存空间(32位操作系统上为4GB)之外分配内存

    请指出我理解中的错误,如果可能的话,请给出一个清晰的描述。

    1)堆内存:JVM进程中用于保存Java对象并由JVM垃圾收集器维护的内存

    2) 本机内存/堆外:是指在进程地址空间内分配的内存,该地址空间不在堆内,因此不会被Java垃圾收集器释放

    3) 直接内存:与本机类似,但也意味着硬件中的底层缓冲区正在共享。例如,网络适配器或图形显示中的缓冲区。这里的目标是减少在内存中复制相同字节的次数

    最后,根据操作系统的不同,可以通过不安全的alloc和/或通过内存映射文件来执行额外的本机分配(分配内存地址空间)。内存映射文件特别有趣,因为它可以轻松地分配比机器当前具有的物理ram更多的内存。另外请注意,总地址空间限制受所用指针大小的限制,32位指针不能超出4GB。句号

    还有一个问题,是否可以直接在JVM进程的总内存空间(32位操作系统上为4GB)之外分配内存

    4GB是32位操作系统上进程的总虚拟地址空间限制。4字节指针不能解决更多的问题

    你唯一能做的就是打开一个大文件,通过有限的内存映射缓冲区与之交互,根据需要映射和释放它们,并希望操作系统页面缓存将它们保存在物理内存中


    如果您需要超过2GB的内存,您真的应该使用64位操作系统和JVM。

    许多在JVM上运行的高性能服务器应用程序都使用堆外内存来提高服务器的性能,例如Apache Cassandra。它过去将大部分数据结构存储在堆上,但在最近的版本中,它一直存储在堆外内存上

    我真的很难理解java和OS提供的内存分段。既然操作系统将进程的地址空间划分为多个段(如堆堆栈数据文本),那么JVM进程内存也将由操作系统提供这些段。现在,当JVM开始执行JAVA程序时,它(JVM)再次提供类似于JAVA程序的分段。现在我真的把这两种类型的内存分割搞糊涂了,它们是由OS提供的,然后由JVM提供给java程序。你能帮我理解这一点吗。