C# 中 RAM 耗尽时会发生什么?

发布于 2024-11-07 05:30:21 字数 288 浏览 1 评论 0原文

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

我做了一些科学计算,并且计算有时需要大量内存来存储其结果。几天前,我的输出文件占用了 4 GB 的硬盘空间,但我有这么大的 RAM。那么:

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

提前致谢!

I'm no computer expert, so let me try to put this question a little bit more specifically:

I do some scientific computations, and the calculations sometimes requires a lot of memory to store their results. A few days ago, I'd an output file that took 4 GB in hard disk, but I have this amount of RAM. So:

  • How does the CLR (or is it something else?) deals with the memory when the program you're running allocates more memory than that available in the computer? Does it create some swap in the HD? (I know that could slow down my program, but I'm only interest in the memory issue)
  • Is it OS-dependent, say if I work with MONO on linux or with VS on Windows?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

回首观望 2024-11-14 05:30:21

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

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

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

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

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

CLR 内存管理器不会为您实现这些奇特的映射和取消映射策略;基本上,您获得了 2GB 地址空间,仅此而已。如果您想做一些奇特的事情,例如使用内存映射文件,则需要您自己编写代码来管理内存。

The way I find helpful to think about it is: memory is disk space. RAM is a fast cache. Rather than thinking "when I'm out of RAM, the system will swap it to disk", I think "when I have available RAM, the system will move my on-disk memory into it".

That's backwards from how most people think about it, but I find it helps. RAM is just a performance optimization; the real limit on how much memory you can allocate is available disk space.

Of course it is more complicated than that. On 32 bit operating systems every process gets a 2 billion byte user address space. (And the same for the kernel address space, but let's ignore that.) Every page of memory you can access, whether it is in RAM or on disk, has to be in that address space. You can have more than 2 billion bytes allocated, no problem. But you can only address 2 GB of it at a time. If you have 10 GB allocated, then at least 8GB of it will not be mapped into address space. In that case you have to unmap something else and then map what you want into the address space in order to get at it.

Moreover, lots of things need to be in contiguous address space. If you have a 1MB stack, for example, then there needs to be a million contiguous bytes available in the address space.

When people "run out of memory" they are not running out of RAM; RAM is just a fast cache over the disk. And they are not running out of disk space; there's plenty of that. They're almost always in a situation where there is insufficient contiguous address space to meet the demand.

The CLR memory manager does not implement these fancy map-and-unmap strategies for you; basically, you get your 2GB address space and that's it. If you want to do something fancy, say with memory mapped files, that's up to you to write the code to manage the memory yourself.

忆离笙 2024-11-14 05:30:21

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

如果您分配的内存多于可寻址的内存,则会发生 OutOfMemoryException

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

If you allocate more memory than physically exists, yes, swap space will be used.

If you allocated more memory than can be addressable, an OutOfMemoryException will occur.

Not sure about Mono, but I would guess that this is runtime dependent and would behave pretty much the same way (not enough physical memory will cause swapping, too much allocated would cause the exception).

倒数 2024-11-14 05:30:21

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

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

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

The run-time just asks the operating system for more memory. The operating system handles paging the existing contents of memory out to disk and otherwise swapping things around to create more free physical memory, if necessary. The same thing happens here for managed C#/.NET programs as happens for regular, unmanaged programs.

The only difference in the world of managed applications is that the .NET run-time imposes some memory overhead, thus limiting the total amount of memory that is actually available for your application. For example, the garbage collector requires some memory space to do its work.

So yes, it's OS-dependent, at least to some extent. However, most modern operating systems have fairly similar approaches to memory management.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文