5

大多数关于虚拟内存的文献都指出,作为应用程序开发人员,了解虚拟内存可以帮助我利用其强大的功能。我参与在 Linux 上开发应用程序已有一段时间了,但在编写代码时并不关心虚拟内存的复杂性。我错过了什么吗?如果是这样,请阐明我如何利用虚拟内存的工作原理。否则,如果我对这个问题没有意义,请告诉我!

4

5 回答 5

4

嗯,这个概念实际上很简单。我不会在这里重复,但你应该拿起任何关于操作系统设计的书,它会在那里解释。我推荐 Silberscahtz 和 Galvin 的“操作系统概念”——这是我在大学时必须使用的,而且很好。

我能想到的虚拟内存知识可能会给你的几件事是:

  • 学习在页面边界分配内存以避免浪费(仅适用于虚拟内存,不适用于通常的堆/堆栈内存);
  • 将某些页面锁定在 RAM 中,这样它们就不会被交换到 HDD;
  • 监护人页面;
  • 保留一些地址范围并稍后提交实际内存;
  • 也许使用 NX(不可执行)位来提高安全性,但我不确定这一点。
  • PAE 用于在 32 位系统上访问 >4GB。

尽管如此,所有这些东西都只能在非常特定的场景中使用。事实上,99% 的应用程序不需要关心这一点。

补充:也就是说,了解所有这些事情绝对是件好事,这样您就可以在出现此类情况时识别它们。请注意 - 权力带来责任。

于 2009-02-04T08:51:53.190 回答
2

这是一个有点模糊的问题。

使用虚拟内存的方式主要是通过使用内存映射文件。有关更多详细信息,请参见 mmap() 手册页。

虽然,您可能无论如何都在隐式使用它,因为任何动态库都是作为映射文件实现的,并且许多数据库库也使用它们。

使用来自高级语言的映射文件的界面通常很不方便,这使得它们不太有用。

使用映射文件的主要好处是:

  • 访问文件的某些部分时没有系统调用开销(这实际上可能是一个缺点,因为页面错误可能无论如何都会有同样多的开销,如果它发生)
  • 无需将数据从操作系统缓冲区复制到应用程序缓冲区 - 这可以提高性能
  • 能够在进程之间共享内存。

一些缺点是:

  • 32 位机器很容易用完地址空间
  • 难以正确处理文件扩展
  • 没有简单的方法来查看当前驻留了多少/哪些页面(但是可能有一些方法)
  • 不适合实时应用程序,因为页面错误可能会导致 IO 请求,从而阻塞线程(但是文件可以锁定在内存中,但前提是内存足够多)。
于 2009-02-04T08:51:57.977 回答
1

对于当今的大多数应用程序,程序员可以不知道计算机内存的工作情况而不会造成任何伤害。但有时——例如,当你想改善程序的占用空间时——你最终不得不自己操作内存。在这种情况下,了解内存的设计方式至关重要。

换句话说,虽然没有它你确实可以生存,但学习虚拟内存只会让你成为一个更好的程序员。

我认为维基百科的文章可以是一个好的开始。

于 2009-02-04T08:45:03.233 回答
1

在 10 种情况下,可能有 9 种情况您无需担心虚拟内存管理。这就是内核的工作。可能在一些高度专业化的应用程序中,您是否需要围绕它们进行调整。

我知道一篇关于计算机内存管理的文章,重点是 Linux [ http://lwn.net/Articles/250967 ]。希望这可以帮助。

于 2009-02-04T08:49:25.563 回答
1

如果您关心性能 - 了解内存层次结构很重要。

对于完全包含在物理内存中的小型数据集,您需要关注缓存(从缓存中访问内存要快得多)。

在处理大型数据集时——可能由于缺少物理内存而被分页,您需要小心保持访问模式的本地化。

例如,如果您在 C ( int a[rows][cols]) 中声明一个矩阵,它是按行分配的。因此,在扫描矩阵时,您需要按行而不是按列进行扫描。否则,您将多次进出相同的数据。

Another issue is the difference between dirty and clean data held in memory. Clean data is information loaded from file that was not modified by the program. The OS may page out clean data (perhaps depending on how it was loaded) without writing it to disk. Dirty pages must first be written to the swap file.

于 2009-02-04T09:25:25.227 回答