6

我不是计算机专家,所以让我试着更具体地提出这个问题:

我做了一些科学计算,计算有时需要大量内存来存储结果。几天前,我有一个在硬盘上占用 4 GB 的输出文件,但我有这么多的 RAM。所以:

  • 当您正在运行的程序分配的内存比计算机中可用的内存多时,CLR(或者是其他什么东西?)如何处理内存?它会在高清中创建一些交换吗?(我知道这可能会减慢我的程序,但我只对内存问题感兴趣)
  • 它是否依赖于操作系统,比如我是在 linux 上使用 MONO 还是在 Windows 上使用 VS?

提前致谢!

4

3 回答 3

12

我觉得有帮助的思考方式是:内存就是磁盘空间。RAM是一种快速缓存。与其思考“当我的 RAM 用完时,系统会将其交换到磁盘”,我认为“当我有可用的 RAM 时,系统会将我的磁盘内存移入其中”。

这与大多数人的想法相反,但我发现它有帮助。RAM只是性能优化;您可以分配多少内存的真正限制是可用磁盘空间。

当然,它比这更复杂。在 32 位操作系统上,每个进程都有一个 20 亿字节的用户地址空间。(内核地址空间也是如此,但让我们忽略这一点。)您可以访问的每一页内存,无论是在 RAM 中还是在磁盘上,都必须在该地址空间中。你可以分配超过 20 亿字节,没问题。但是您一次只能寻址 2 GB。如果分配了 10 GB,那么至少有 8 GB 不会映射到地址空间。在这种情况下,您必须取消映射其他内容,然后将您想要的内容映射到地址空间中才能得到它。

此外,很多东西需要在连续的地址空间中。例如,如果您有一个 1MB 的堆栈,那么地址空间中需要有一百万个连续字节可用。

当人们“内存不足”时,他们并没有用完 RAM;RAM 只是磁盘上的快速缓存。而且它们并没有耗尽磁盘空间;有很多这样的。他们几乎总是处于连续地址空间不足以满足需求的情况。

CLR 内存管理器不会为您实现这些花哨的 map-and-unmap 策略;基本上,您将获得 2GB 的地址空间,仅此而已。如果你想做一些花哨的事情,比如内存映射文件,那取决于你自己编写代码来管理内存。

于 2011-05-14T14:15:09.560 回答
3

如果您分配的内存多于实际存在的内存,是的,将使用交换空间。

如果您分配的内存超出了可寻址的范围,OutOfMemoryException则会发生 an 。

不确定 Mono,但我猜这取决于运行时并且行为方式几乎相同(没有足够的物理内存会导致交换,分配过多会导致异常)。

于 2011-05-14T13:31:53.077 回答
3

运行时只是要求操作系统提供更多内存。操作系统处理将内存的现有内容分页到磁盘,并在必要时进行交换以创建更多可用的物理内存。托管 C#/.NET 程序与常规非托管程序发生的情况相同。

托管应用程序领域的唯一区别是 .NET 运行时会产生一些内存开销,从而限制了应用程序实际可用的内存总量。例如,垃圾收集器需要一些内存空间来完成它的工作。

所以是的,它依赖于操作系统,至少在某种程度上是这样。然而,大多数现代操作系统都有非常相似的内存管理方法。

于 2011-05-14T13:32:17.100 回答