我不是计算机专家,所以让我试着更具体地提出这个问题:
我做了一些科学计算,计算有时需要大量内存来存储结果。几天前,我的输出文件占用了4 GB的硬盘,但我有这么多的RAM。所以:
提前致谢!
答案 0 :(得分:11)
我认为有用的方法是:内存是磁盘空间。 RAM 是一个快速缓存。我认为“当我有可用的RAM时,系统会将我的磁盘存储器移入其中”,而不是“当我没有RAM时,系统会将其交换到磁盘”。
这与大多数人对此的看法相反,但我发现它有所帮助。 RAM只是一种性能优化;您可以分配多少内存的实际限制是可用磁盘空间。
当然比这更复杂。在32位操作系统上,每个进程都有一个20亿字节的用户地址空间。 (对于内核地址空间也是如此,但让我们忽略它。)你可以访问的每一页内存,无论是在RAM中还是在磁盘上,都必须在该地址空间中。你可以分配超过20亿个字节,没问题。但是你一次只能处理2 GB的内容。如果分配了10 GB,则至少8 GB不会映射到地址空间。在这种情况下,您必须取消映射其他内容,然后将您想要的内容映射到地址空间以便获取它。
此外,很多事情都需要在连续的地址空间中。例如,如果您有1MB的堆栈,那么地址空间中需要有一百万个连续的字节。
当人们“内存不足”时,他们没有用完RAM; RAM只是磁盘上的快速缓存。它们没有耗尽磁盘空间;有很多。他们几乎总是处于没有足够的连续地址空间来满足需求的情况。
CLR内存管理器不会为您实现这些精美的map-and-unmap策略;基本上,你得到2GB的地址空间,就是这样。如果你想做一些花哨的事情,比如内存映射文件,你可以自己编写代码来管理内存。
答案 1 :(得分:3)
如果您分配的内存超过物理存在,是的,将使用交换空间。
如果分配的内存多于可寻址的内存,则会出现OutOfMemoryException
。
不确定Mono,但我猜这是依赖于运行时的,并且表现方式几乎相同(没有足够的物理内存会导致交换,分配太多会导致异常)。
答案 2 :(得分:3)
运行时只是要求操作系统获得更多内存。操作系统处理将内存的现有内容分页到磁盘,并在必要时交换内容以创建更多的空闲物理内存。对于托管的C#/ .NET程序,同样的事情发生在普通的非托管程序中。
托管应用程序世界的唯一区别是.NET运行时会产生一些内存开销,从而限制了应用程序实际可用的内存总量。例如,垃圾收集器需要一些内存空间来完成它的工作。
所以是的,它依赖于操作系统,至少在某种程度上如此。但是,大多数现代操作系统都有类似的内存管理方法。