堆外,本机堆,直接内存和本机内存

时间:2015-06-03 14:20:48

标签: java memory jvm

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

现在我将它们描述为:

  1. 本机内存表示普通JVM堆之外的内存区域,但仍然在操作系统为JVM进程保留的总用户空间内存中(例如,在32位Windows上,它默认为2 GB) 。 JVM保留此空间以存储一些内部数据,例如“永久生成/方法区域”等。
  2. 直接内存表示您通过java.nio.DirectByteBuffer使用本机内存。

  3. 原生堆表示您通过unsafe.allocateMemory使用本机内存或只是在JNI代码中执行malloc

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

  5. 另外一个问题是,是否可以直接在总内存空间(32位操作系统上为4GB)之外分配内存,以备JVM进程使用?

    请指出我理解中的错误,如果可能的话,请对其进行明确说明。

3 个答案:

答案 0 :(得分:11)

1)堆内存:由JVM管理以表示Java对象的JVM进程内的内存

2)本机内存/堆外:是在不在堆内的进程地址空间内分配的内存。

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

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

答案 1 :(得分:1)

  

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

4GB是32位操作系统上进程的总虚拟地址空间限制。 4字节指针根本无法解决这个问题。

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

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

答案 2 :(得分:0)

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