- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在学习这些主题并阅读了许多文章和书籍,但它们都缺乏一些补充信息,使我更加困惑。所以在这里,我想解释一下我在提问时所知道的。希望这个话题对像我这样的人有用。如有必要,我还想了解我的知识的有效性和更正。
虚拟内存
有些文章说“虚拟内存是硬盘的一些空间,它模拟物理内存,以便我们可以拥有比实际更多的内存。”。其他一些文章说“虚拟内存是物理内存(RAM)的组合,这是硬盘的一部分,其作用类似于物理内存和页表。”然而,它们是不同的东西,我不明白为什么会有这样不同的解释。
让我们继续第二个解释,因为它也是维基百科描述虚拟内存的方式。在这一点上,虚拟地址是有意义的,因为我们在虚拟内存中使用地址而不是直接使用物理内存。
顺便说一下,我的 Mac 说我有 8GB 物理内存和 8GB 虚拟内存。在这种情况下,VM 包括物理内存还是 HD 中用作内存的空间量?我的程序是否有 16GB 内存可用?
问题一:
Intel i5 有 36 位地址总线,这意味着您可以寻址 64GB 内存。假设我在我的电脑上安装了 4GB 内存。但是,我的程序可能不知道安装的内存大小,因为它将用于具有不同内存大小的许多不同系统。这是虚拟内存变得方便的地方。它抽象出安装的内存的实际大小。
但是,当我的程序想要访问内存地址 0xFFFFFFFFF 时会发生什么?我只安装了 4GB,也许还有一些高清内存空间。
对于这个问题,我有两个理论:
1. 由于页表由 OS 维护,因此 OS 对该地址进行解码并找出是哪个页,并在页表中检查该页以查看它们是否具有与之关联的物理地址(有效和无效标志),如果是,则转到物理地址页面入口点在物理内存中+在虚拟地址中定义的偏移量并带来该值。否则会发生页面错误,操作系统会在辅助存储中查找该页面,获取它并将其放入内存中并更新页表。
2. 它抛出一个 OutOfMemory 类型的异常,表示我没有给定地址可以寻址的任何内存。
第一种理论的缺点是,当程序想要使用 64GB 内存时会发生什么?然后我们需要有 60GB 的 HD 内存空间,因为我们只有 4GB。然而,在 MAC 下面的屏幕截图中告诉我只有 8GB 的虚拟内存。
问题2:
进程如何放入虚拟内存?我的意思是每个进程都有 0x0 - 0xFFFFFFFFF 可用的虚拟内存空间,还是只有一个虚拟内存地址空间用于放置所有进程?
如果每个进程都假设他们拥有所有可用的内存,那么内存看起来如下:
如果只有一个虚拟内存概念,那么它看起来像这样:
页表
所以页表是一种位于物理地址和虚拟地址之间的数据结构。它是一个关联数组(或像字典),对于每个页面(键),都有一个关联的物理地址(值)。
操作系统使用 MMU(内存管理单元)来执行从虚拟地址到物理地址的转换。
问题三:
是否有一个包含每个进程的所有页面的巨型页表或每个进程都有自己的页表?
寻呼
分页是一种内存管理方法。内存管理单元将虚拟内存和物理内存划分为页面(固定且大小相同的块)。当您在内存和辅助存储之间交换页面时,此技术很有用,以便您可以在它们之间交换页面。例如,您的程序请求位于地址中的数据。但是,您的程序使用的地址是虚拟地址,MMU 使用页表对其进行转换。在此期间,MMU 检查页表是否存在请求的页表,如果不存在,操作系统从二级存储中获取它并更新页表。
问题 4:
假设一个进程从一个地址请求数据,该地址被转换为一个已经有一些数据的物理地址。怎么知道数据不属于请求者进程,应该用二级存储中的数据替换?
例如,有脏位用于是否将该页面写回硬盘,但我认为这不是决定所有者进程的因素。
最佳答案
有些人使用术语“虚拟内存”,好像它是页面文件的同义词,因为页面文件代表了你分配的内存中不是“真实”内存(即 RAM)的部分。但大多数人认为“虚拟内存”是操作系统赋予程序的整个抽象层,它结合了 RAM 和页面文件。
我不确定 Mac OS 偏爱这些定义中的哪一个,尽管您的计算机似乎不太可能没有分配任何分页内存,所以我猜它可能会向您的 8GB 实际 RAM 添加 8GB 分页内存,总共 16GB 的可用(虚拟)内存。
请记住,因为操作系统管理内存分配和释放请求,所以它可以自由地做任何它想做的事情。我的理解是,大多数操作系统对每个进程都有不同的内存分配表,因此它们实际上可以为多个程序提供相同的虚拟内存地址,但这些内存地址将映射到内存中不同的实际块。因此,64 位操作系统可以将最大数量的 32 位地址分配给多个 32 位程序——它们并不都限于相同的 32 位内存地址。
但是,存在限制:操作系统可以将限制设置为允许页面文件增长到的大小。因此,除非您故意告诉操作系统这样做,否则它可能不会有 64 GB 的总虚拟内存。即使这样做了,它也不能将所有 64 GB 分配给每个程序,因此您很可能会有一个 OutOfMemory
操作系统在 0xFFFFFFFFF
分配虚拟地址之前出错到你的程序。 (事实上,得知 0xFFFFFFFFF
实际上是一个保留的错误代码位置,类似于 0x0
,我不会感到惊讶。)但是由于您的程序知道的地址与真正的内存地址没有相关性,因此您最终会被分配一个您的程序认为是 0xFFFFFFFFF
的内存地址的可能性。 ,即使操作系统没有使用接近那么多内存的地方。
Is there one big giant page table which includes all the pages for every process or each process has its own page table?
0x00000002
处分配了内存。 ,当它从该内存地址中加载值时,操作系统可能会识别出这实际上映射到实际内存地址
0x00000F23
,这就是内存地址,其值将被实际提取到 CPU 寄存器中。或者,它可能意识到它已将包含该地址的页面移动到磁盘上的某个位置,在这种情况下,操作系统将找到内存的空白部分,并首先将页面的数据从磁盘加载到该内存中。 (同样,这个内存地址与程序请求的原始内存地址没有任何关联。)
关于paging - 了解虚拟地址、虚拟内存和分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22290347/
有WHERE 1=1有什么作用如果您在脚本(伪代码)中编写此请求: sql = "SELECT f1,f2,f3 FROM t WHERE 1=1" ++ restOfTheClause
这个问题已经有答案了: R: Convert delimited string into variables (3 个回答) 已关闭 5 年前。 我有一个包含电影数据的表,在最后一列中,它包含电影所属
假设我有一个基类: struct A{ virtual void foo() = 0; }; 然后假设我有一个这样的派生类: struct B : public virtual A{ voi
我有一个小问题,我的 << 运算符没有被正确调用。 这是我的: class SomeInterface { friend std::ostream& operator<<(std::ostrea
首先,我来自 Java 社区,并且仍然是 C++ 的学习者。 请看下面的类 第二张图片显示了类“GameObject”的子类。它还有一个 Display() 方法。 GameObject类有5个子类,
我这里遇到了一些问题。我试图让我的代码像 java 中的接口(interface)一样工作。这个类被其他 2 个继承,因为它们导致了一些问题。而且我还想知道我是否做对了,以及改进我的代码的方法。我是新
在 C++ 中,我有一个基类 A,一个子类 B。两者都有虚方法 Visit。我想在 B 中重新定义“访问”,但 B 需要访问每个 A(以及所有子类)的“访问”功能。 我有类似的东西,但它告诉我 B 无
我有一个抽象类,它是类层次结构的根。该根类有一个带有一些简单实现的方法,似乎没有必要随时随地更改该实现。 使该方法成为非虚方法很好,但是某些子类可能会意外地重新实现它。在这种情况下,虚拟 final方
在 MSDN 上,我发现在抽象方法声明中使用“virtual”修饰符是错误的。我的一位同事应该是非常有经验的开发人员,但他在他的代码中使用了这个: public abstract class Busi
C++ 虚函数表是仅用于确定调用虚函数时应该执行哪一段代码,还是在运行时有其他用途? 在维基百科上,它列出了“动态调度”作为一个原因,但没有深入了解 C++ 的更多细节...... 最佳答案 一些实现
页面大小是否恒定?更具体地说,getconf PAGE_SIZE 给出 4096,这很公平。但这可以通过程序的运行时间改变吗?或者它在整个操作系统进程生成过程中是否保持不变。 IE。 , 进程是否可能
析构函数(当然还有构造函数)和其他成员函数之间的区别在于,如果常规成员函数在派生类中具有主体,则仅执行派生类中的版本。而在析构函数的情况下,派生版本和基类版本都会被执行? 很高兴知道在析构函数(可能是
如果一个函数被定义为虚函数并且与纯虚函数相同,这究竟意味着什么? 最佳答案 来自 Wikipedia's Virtual function... In object-oriented programm
我有一个在 Jetty 下运行的应用程序,我希望该应用程序返回自引用绝对 URL(生成 RSS 提要时,因此客户端必须能够在没有“当前 URL”上下文的情况下工作)。 问题是我事先不知道应用程序将部署
如何在两个virtualtreeview之间复制以复制所有列,而不仅仅是第一列? 复制前: 复制后: 最佳答案 树控件不保存任何数据。它不包含要显示的列数据,因此无法复制它。而是,当树控件想要显示任何
我已将 ShowHint 设置为 true 并将 HintMode 设置为 hmToolTip,但是当我将光标悬停在控件上时,我的 OnGetHint() 事件处理程序甚至没有断点。 知道我做错了什么
我的 friend 正在 Delphi 中使用 VirtualTreeView 工作,并且遇到了下一个问题:他有两列,第一列的每一行都有数据和子项。是否可以不更改第一列宽度来设置最大子列宽度? 图例:
我在我的 Virtual TreeView Component 中使用 TVirtualStringTree ( Delphi project 的一部分)我想创建一个 View ,其中 2 列可以有可
我想遍历 VirtualTreeView 的所有根并将其删除。 我不想清除它。 我收到此代码的访问冲突: var Node : PVirtualNode; begin if VirtualStri
我有一个可以输出表单的 PHP 文件。我想在服务器端调用这个 PHP 文件(当前使用“include”),填写并提交。 这样更好,因此我不必干预实际的 PHP 表单,只需处理表示层,以便数据可以被它自
我是一名优秀的程序员,十分优秀!