java - Java 中的连续页面/物理内存

标签 java memory-management operating-system x86 paging

我的目标是确保在java中分配的数组是跨连续的物理内存分配的。我遇到的问题是,数组分配的页面在物理内存中往往不是连续的,除非我分配一个非常大的数组。

我的问题是:

  • 为什么一个非常大的数组可以确保 物理内存中连续的页面?
  • 有什么方法可以确保数组在物理内存中分配,而不需要使数组变得很大?
  • 如何在不测量缓存命中/缓存未命中的情况下判断 Java 对象/数组存在于哪个页面或物理地址?

我不是在寻找答案来询问为什么我在 java 中这样做。我知道 C 会“解决我的问题”,并且我违背了 java 的基本性质。尽管如此,我这样做还是有充分的理由的。

不需要保证答案始终有效。我正在寻找大多数时候有效的答案。对于任何一个理性的 Java 程序员都不会写出的创造性的、开箱即用的答案,可以加分。特定于平台(x86 32 位 64 位)是可以的。

最佳答案

没有。物理上连续的内存需要与操作系统直接交互。大多数应用程序(包括 JVM)仅获取虚拟连续的地址。 JVM 无法为您提供它无法从操作系统获得的东西。

此外,你为什么想要它?如果您要设置 DMA 传输,那么您可能正在使用 Java 以外的技术。

背景位:

现代 PC 中的物理内存通常是灵活的数量,位于可更换的 DIMM 模块上。它的每个字节都有一个物理地址,因此操作系统在引导期间确定哪些物理地址可用。事实证明,应用程序不直接使用这些地址会更好。相反,所有现代 CPU(及其缓存)都使用虚拟地址。存在到物理地址的映射表,但这不需要是完整的——通过使用未映射到物理地址的虚拟地址来启用到磁盘的交换。每个进程有一个表(具有不完整的映射)可以获得另一级别的灵 active 。如果进程A有一个映射到物理地址X的虚拟地址,但进程B没有,那么进程B就无法写入物理地址X,我们可以认为该内存是进程A独占的。显然为了安全起见,操作系统必须保护对映射表的访问,但所有现代操作系统都会这样做。

映射表在页面级别工作。页或物理地址的连续子集被映射到虚拟地址的连续子集。开销和粒度之间的权衡导致 4KB 页面成为常见的页面大小。但由于每个页面都有自己的映射,因此不能假设超出该页面大小的连续性。特别是,当页面从物理内存中逐出、交换到磁盘并恢复时,很可能最终会到达新的物理内存地址。程序不会注意到,因为虚拟地址没有改变,只有操作系统管理的映射表改变了。

关于java - Java 中的连续页面/物理内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/829987/

相关文章:

python - 有没有一种Pythonic方法来检查操作系统是否是64位Ubuntu?

c - 键盘 IRQ 仅触发一次

java - 在 Java 中反转 LinkedList

java - 我的多维数组代码无法正常工作

java - Runtime.getRuntime() 不在服务器中提供输出

iphone - 开始对 OS X 进行逆向工程?

java - 有没有办法在应用程序启动时以编程方式设置特定的终端字体?

java - 将 MimeMessage 对象消息作为常规转发格式转发,而不是 EML 文件中的附件

Linux内核内存管理,它是否一直使用连续的内存页?

linux - 为什么我可以在/proc/pid/maps 输出中看到几个相同的段?