Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 阵列如何存储在虚拟内存中?_Java_C_Operating System_Virtual Memory - Fatal编程技术网

Java 阵列如何存储在虚拟内存中?

Java 阵列如何存储在虚拟内存中?,java,c,operating-system,virtual-memory,Java,C,Operating System,Virtual Memory,如果你有一个数组 int arr[100]; 在一台显然使用虚拟内存运行的现代机器中,这到底是如何存储的 我知道我们必须使用虚拟内存分页,因为数组是一个连续的块,如果我们有一个4kb的页面,这个数组arr将适合一个页面 但是这个页面是存储在磁盘还是RAM上 我知道我们必须使用虚拟内存分页 您不必使用分页。您可以关闭寻呼 如果我们有一个4kb的页面,那么这个数组arr将适合一个页面 它可能适合4kb页面,但很可能不会在4kb边界上(或附近)对齐,因此实际上,它可能会跨两个页面存储 此页存储在磁盘

如果你有一个数组

int arr[100];
在一台显然使用虚拟内存运行的现代机器中,这到底是如何存储的

我知道我们必须使用虚拟内存分页,因为数组是一个连续的块,如果我们有一个4kb的页面,这个数组
arr
将适合一个页面

但是这个页面是存储在磁盘还是RAM上

我知道我们必须使用虚拟内存分页

您不必使用分页。您可以关闭寻呼

如果我们有一个4kb的页面,那么这个数组
arr
将适合一个页面

它可能适合4kb页面,但很可能不会在4kb边界上(或附近)对齐,因此实际上,它可能会跨两个页面存储

此页存储在磁盘或RAM上吗


数组与其他数据结构没有什么不同。它们存储在内存(RAM)中,除非操作系统在内存不足的情况下将其换出磁盘。

总之,数据可能位于不同的位置,并且可能会自动更改(通过操作系统的操作),在正常程序中工作时,通常不需要了解它

首先,在源代码中声明数组并不一定意味着在内存中创建完整数组或任何数组。编译器可以以消除部分或全部数组的方式优化源代码

但是,让我们假设数组是实际创建的。创建虚拟内存是为了呈现一种错觉,即进程独占使用物理内存和/或其内存比实际可用的物理内存多。这种错觉的一个目的是,流程不必关心其数据的实际位置。而绝大多数正常过程都可以忽略这一点

而且,在大多数情况下,编译器很少注意小对象相对于页面边界的位置。通常情况下,将100
int
数组放置在一个页面内或跨过页面边界都没有什么区别

当有必要知道或影响数据的实际位置时,会出现一些问题

有几种方法可以影响数据相对于页面边界的位置,可以为此使用系统调用或库调用,也可以分配多余的内存,然后将数据放在其中选定的位置

如果数据很重要,并且首选或需要保留在物理内存中,则可能会有系统调用(当然取决于系统)来请求该数据

在没有此类特定请求的情况下,数据的位置取决于许多因素。如果声明
int
的静态数组,并使用编译时数据对其进行初始化,则数据可能会出现在最终生成的可执行文件的某个部分中。在某些系统中,启动可执行文件时,系统不会将整个文件加载到内存中。它仅在引用可执行文件时才从可执行文件加载数据的各个部分。因此,这些数据最初可能驻留在磁盘上。加载到内存后,如果系统负担了其他需要内存的东西,则系统可能会从内存中丢弃这些数据,使其再次仅存在于磁盘上的可执行文件中

另一方面,如果数据是在程序执行期间生成的,那么当程序生成数据时,它当然在内存中。不过,如果系统有其他需求,系统可能会从内存中删除数据。在这种情况下,由于数据不存在于磁盘上(与可执行文件中的数据一样),因此首先将数据写入磁盘上的页面或交换文件


通常,数据的位置可能会随时间而变化。

一个100个8字节的数组
int
,其对齐要求为8个字节,分配给从潜在页面偏移的均匀分布中随机选择的位置,跨越页面边界的概率为99/(4096/8)=99/512。对于四字节
int
,它是99/1024。这个答案中关于数组“可能存储在两个页面上”的说法是不正确的。@EricPostischil
int
是4个字节,所以不知道“8个字节
int
”来自哪里,但你是对的,我把
int[100]
读作
int[1000]
int[100]
很可能在1页内,而不是跨2页。这是一个显示一般对象计算的示例。谢谢。我现在想知道,如果我访问这个阵列,它会被存储在CPU缓存中,以便下次访问可以更快吗?假设我正在线性扫描代码中的数组。回答得很好!由于这是用
java
标记的,因此如果真的需要,您可以使用
-XX:+AlwaysPreTouch
启动VM,以在每个页面上预触零。通常,如果某些数据位于同一缓存线上,而不是页面上,您会更加关心(当然,如果您这样做的话)。因此,如果数组最初是创建的,存储在RAM中并被访问,然后是否将其存储在
CPU缓存中
,以便我们以后可以更快地访问?@BrijendarBakchodia:缓存通常由处理器自动管理。当处理器从主内存加载某些内容时,它通常会在缓存中保留一个副本,以备将来加载或存储。当处理器将某些内容存储到内存中时,它还可以在缓存中创建副本。然而,缓存方案中有许多变体,在注释中要讨论的内容太多,对于单个堆栈溢出问题来说可能太多。通常,当东西在缓存中时,它们是主内存的副本;缓存中的数据没有从主内存中删除。好的,我明白了。例如,是否可以在缓存中存储二叉树结构?struxt有左右指针,所以我想每次索引tlb都会很昂贵。另一方面,数组是连续存储的,因此可以缓存?@BrijendarBakchodia:Cache