【问题标题】:What is the difference between off-heap, native heap, direct memory and native memory?堆外、本机堆、直接内存和本机内存有什么区别?
【发布时间】:2015-06-03 14:20:47
【问题描述】:

最近我在学习 JVM 内部时遇到了这些概念。我知道关于 SO 已经有很多关于它们的问题,但我仍然无法掌握它们之间的关系,或者说它们是什么。

现在我这样描述它们:

  1. 本机内存是指正常 JVM 堆之外的内存区域,但仍在操作系统为 JVM 进程预留的总用户空间内存范围内(例如在 32 位 Windows 上,默认为 2 GB) .这个空间是JVM预留的,用来存放一些内部数据,比如Permanent Generation / Method Area等。

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

  3. 本机堆意味着您通过unsafe.allocateMemory 使用本机内存,或者在您的JNI 代码中简单地使用malloc

  4. 堆外与本机内存相同。

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

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

【问题讨论】:

    标签: java memory jvm


    【解决方案1】:

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

    2) Native memory/Off-heap:在进程地址空间内分配的内存不在堆内,因此不会被 Java Garbage Collector 释放。

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

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

    【讨论】:

    • 我真的很难理解 java 和 OS 提供的内存分段。既然 OS 将进程的地址空间划分为多个段,如堆堆栈数据文本,同样 JVM 进程内存也会有 OS 提供的这些段。现在,当 JVM 开始执行 JAVA 程序时,它(JVM)再次为 Java 程序提供类似的分段。现在我真的很困惑这两种类型的内存分段,由OS提供,然后由JVM提供给java程序。你能帮我理解一下吗?
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      4GB 是 32 位操作系统上进程的总虚拟地址空间限制。 4 字节指针根本无法寻址更多。

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

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

      【讨论】:

        猜你喜欢
        • 2015-09-16
        • 2015-12-16
        • 2016-10-12
        • 1970-01-01
        • 2016-12-01
        • 1970-01-01
        • 2011-03-29
        • 1970-01-01
        • 2013-09-16
        相关资源
        最近更新 更多