应用程序(和操作系统)如何处理非常大的文件?

DrS*_*ove 5 video memory

例如,我有 11.8 Gb 的视频文件,但我的 RAM 内存只有 2 Gb。VLC(或其他软件)如何处理它?他们如何将其加载到内存中?我使用 VMMap 工具(来自 sysinternals)来查看内存,我看到:

私人160000K

工作集 100000K

显然,它远小于 11.8 Gb - 那么它是怎么发生的呢?

这个问题不仅与视频有关。我想知道计算机通常如何处理非常大的文件。

And*_*aKo 4

这非常复杂,甚至很难开始解释,所以我只会提到程序运行的一些基本方式。

第一种也是最明显的方法,通常也是最慢的方法是直接处理磁盘上的文件。基本上,磁盘上的每个块都有自己的逻辑地址,应用程序可以直接使用磁盘上的数据。因此,如果我正在设计一个简单的文本编辑器,我可以将文本屏幕从磁盘加载到视频内存中,并在做出任何更改后立即将其直接写入磁盘。这种方法(据我所知)由于其众多缺点,如今几乎从未使用过。第一个问题是,与 RAM 相比,磁盘速度非常慢,CPU 实际上会花费所有时间等待磁盘完成数据更新。好处是我们几乎不使用 RAM,因为磁盘中的所有数据都可以直接传输到显卡中的 RAM。最重要的是,现代操作系统使得直接访问硬件变得更加缓慢,并且在许多情况下是不可能的。

接下来,我们有一个(不幸的是)常见且最明显的解决磁盘访问速度慢问题的解决方案:我们只需将整个文件复制到 RAM 并处理 RAM 副本。完成后,我们将以某种方式将 RAM 版本与磁盘上的版本同步并解决问题。现代操作系统使这变得相对容易,因为应用程序程序员可以使用操作系统提供的服务来更新文件,而无需过多考虑它是如何完成的。这种方法的主要优点是速度。RAM(与磁盘相比)速度极快,并且当需要传输大量数据时,磁盘通常工作得更好。此外,这种方法使磁盘可供其他应用程序使用,并且您可以在另一个应用程序正在使用该磁盘时编辑该文件。缺点是假设整个文件可以在合理的时间内加载到 RAM 中,并且该文件将为 RAM 中的其他任务留下足够的空间。有时这不是真的。例如,我曾经不得不打开一个约 3.5 GiB 的文本文件,结果发现大多数应用程序都认为该文本文件适合 RAM。

当我们处理需要大文件的应用程序时,通常使用的下一种方法是将文件的一部分加载到 RAM 中并使用它。完成后,我们将该部分保存到磁盘并读取下一部分。具体如何工作取决于文件本身的结构。
在某些文件类型中,您可能会在文件的开头找到一个索引,您可以将其加载到 RAM 中,并使用它来确定文件中感兴趣部分的逻辑地址。在某些其他文件类型中,您可能需要在整个文件中搜索包含所需数据的部分,然后将文件的该部分加载到 RAM 中。

这种方法还为巧妙的优化提供了空间,例如允许编辑文件的一部分,同时将另一部分在后台加载到 RAM 中,以最大限度地减少打开文件所需的等待时间等。

因此,在视频文件示例中,有关格式本身的一些数据将在精细开始时进行编码,稍后,播放文件的程序将只需要在内存中保存当前正在播放的文件部分。为了使播放更加流畅,程序还会将部分未播放的文件保留到RAM中。通常,准确确定磁盘访问数据需要多长时间并不容易。例如,由于碎片,文件的一部分可能位于磁盘的开头,而一部分可能位于磁盘的末尾。此外,在播放视频的同时,另一个应用程序可能会尝试将大量数据写入磁盘。由于视频播放器在 RAM 中已经有一些缓冲区,因此播放应该继续,不会出现明显的中断。

这种方法的优点是比以前使用更少的 RAM,同时对于程序员预测的用途来说速度相当快。缺点是您依赖程序员来预测文件的哪些部分将被常用以及如何使用,有时预期的使用模式可能与实际使用模式不同。另一个缺点是需要花费精力来精确确定文件的哪一部分需要位于 RAM 中以及该部分需要有多大。如果部件太小,您就无法获得足够的速度;如果部件太大,您就会占用 RAM。

总结一下我描述的 3 个选项:第一个选项是小学的孩子,他在努力阅读一个单词的同时用铅笔在他看到的每个字母下划线。

第二种是将整个文本打印在一页上,如果页面像墙一样大,那么我们可能会遇到一些问题。

第三种选择就像读书一样。您在某一页打开书,而在该页旁边您又打开了另一页!读完这两本后,您将继续阅读下一对。

请注意,在这个答案中,我没有过多讨论现代计算机中磁盘、RAM 和处理器之间存在的无数缓存和抽象层。例如,在现实世界中,如果您有一个程序正在执行大量磁盘访问,而另一个程序尝试保存一个小文件,则该文件可能会存储在 RAM 缓存中的某个位置,直到磁盘有足够的空闲时间来写入它。此外,磁盘本身也有其内部缓存,在将文件写入磁盘之前,它可能会将文件存储在那里一段时间。此外,在读取时,操作系统本身可能会向 RAM 加载比应用程序要求的更多的磁盘块,因为它(无论正确与否)预测应用程序可能很快就会需要它们。磁盘缓存也是如此。然后可能会发现该磁盘实际上不是磁盘,而是 RAID,并且我们在 raid 控制器和每个单独的磁盘上都有缓存,等等。