最近我在学习JVM内部时遇到了这些概念。我知道关于它们已经有很多关于它们的问题,但我仍然无法理解它们之间的关系,或者它们是什么。
现在我将它们描述为:
java.nio.DirectByteBuffer
使用本机内存。unsafe.allocateMemory
使用本机内存,或者只是在JNI代码中执行malloc
。另外一个问题是,是否有可能直接在总内存空间(32位操作系统上为4GB)之外的内存中分配内存?
请指出我理解中的错误,如果可能的话,请对其进行清楚的描述。
1)堆内存:JVM进程内的内存,由JVM管理以表示Java对象
2)本机内存/堆外:是在不在堆内的进程地址空间内分配的内存。
3)直接内存:类似于本机,但也意味着正在共享硬件中的底层缓冲区。例如网络适配器或图形显示中的缓冲区。这里的目标是减少在内存中复制相同字节的次数。
最后,根据操作系统,可以通过Unsafe alloc和/或通过内存映射文件来执行额外的本机分配(分配存储器地址空间)。内存映射文件特别有趣,因为它可以轻松地分配比机器当前具有的物理内存更多的内存。另请注意,总地址空间限制受所使用指针大小的限制,32位指针不能超出4GB。期。
另外一个问题是,是否有可能直接在总内存空间(32位操作系统上为4GB)之外的内存中分配内存?
4GB是32位操作系统上进程的总虚拟地址空间限制。 4字节指针根本无法解决更多问题。
你唯一能做的就是打开一个大文件并通过有限数量的内存映射缓冲区与它进行交互,根据需要映射和释放它们,并希望操作系统页面缓存将它们保存在物理内存中。
如果你需要超过2GB的内存,你真的应该使用64位操作系统和JVM。
许多在JVM上运行的高性能服务器应用程序都使用堆外内存来提高服务器的性能,例如Apache Cassandra。它用于在堆上存储大部分数据结构,但在最近的版本中,它已存储在堆外内存中