为什么我得到的System.OutOfMemoryException即使有关于RAM 700MB免费的吗? [英] why do I get System.OutOfMemoryException even when there is about 700Mb of RAM free?

查看:248
本文介绍了为什么我得到的System.OutOfMemoryException即使有关于RAM 700MB免费的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行一些测试,看我的日志将如何执行的,而不是做 File.AppendAllText 我会先写一个内存流,然后复制到文件。所以,正好看到快速的内存运行如何我这样做。

 私人无效的button1_Click(对象发件人,EventArgs五)
{
使用(VAR memFile =新System.IO.MemoryStream())
{
使用(VAR体重=新System.IO.BinaryWriter(memFile))
{
的for(int i = 0; I< Int32.MaxValue,我++)
{
bw.Write(i.ToString()+ Environment.NewLine);
}
bw.Flush();
}
memFile.CopyTo(新System.IO.FileStream(System.IO.Path.Combine(C,memWriteWithBinaryTest.log),System.IO.FileMode.OpenOrCreate));
}
}

I 达到 25413324 我得到了类型'的System.OutOfMemoryException'的引发的异常。尽管我的< A HREF =http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx相对=nofollow> Process Explorer的说我有免费的RAM ??? 700MB的



下面是屏幕截图(以防万一)



Process Explorer的



下面是在WinForm





修改:用于多个对象的缘故而在堆上创建,我改写了 bw.write 这个

  bw.Write(I) 


解决方案

首先,您运行的内存,因为你在的MemoryStream 积累,而不是直接写它的的FileStream 数据。使用的FileStream 直接,你会不会在所有需要太多的RAM(但你必须保持文件打开)。


$ B $ :b

的物理存储器未使用的量没有这种例外直接相关的,因为奇怪,因为这可能听起来



重要的是:




  • 您已经对内存中的进程提供一个连续的大块'的的虚拟地址空间

  • 该系统提交不超过总RAM大小+页面文件大小



当你问Windows内存管理器来分配你一些RAM ,它需要检查是不是多少可用的,但它拥有多少的答应的以提供给所有其它进程。这些有希望的是通过提交完成。要的提交的一些内存意味着内存管理器提供您一个保证,它的将会的可当你终于利用它。



因此,它可以是物理RAM完全用完,但你的分配请求仍成功。为什么?因为有大量的空间中的页文件中获得。当你真正开始使用你得到了RAM通过这样的分配,内存管理器将只是简单的页面了别的东西。 !所以0的物理内存=分配都将失败。



相反也可以发生;尽管有一些未使用的物理内存分配可能会失败。您的过程中,通过所谓的虚拟地址空间的看到的内存。当你的进程读取地址 0x12340000 的内存,这是一个虚拟地址。它可以映射到RAM中的 0x78650000 ,或 0x000000AB12340000 (运行在64位操作系统的32位进程),它可能指向的东西,只有在页面文件存在,也可能不什么都平衡点。



当要分配的内存块与相邻的地址,这是在该RAM中需要是连续的这个虚拟地址空间。对于一个32位的过程中,你只能得到2GB或可用地址空间3GB,因此,它不是太难的这样一种方式,有足够的尺寸不连续的大块存在使用它,尽管那里是既自由物理内存和足够的总未用虚拟地址空间。


I was running some test, to see the how my logging would perform is instead of doing File.AppendAllText I would first write to a memory stream and then copy to file. So, just to see how fast memory operation is I did this..

private void button1_Click(object sender, EventArgs e)
    {
        using (var memFile = new System.IO.MemoryStream())
        {
            using (var bw = new System.IO.BinaryWriter(memFile))
            {
                for (int i = 0; i < Int32.MaxValue; i++)
                {
                    bw.Write(i.ToString() + Environment.NewLine);
                }
                bw.Flush();
            }
            memFile.CopyTo(new System.IO.FileStream(System.IO.Path.Combine("C", "memWriteWithBinaryTest.log"), System.IO.FileMode.OpenOrCreate));
        }
    }

When i reached 25413324 I got a Exception of type 'System.OutOfMemoryException' was thrown. even though my Process Explorer says I have about 700Mb of free ram???

Here are the screen shots (just in case)

Process Explorer

Here's the winform

EDIT : For the sake of more objects being created on heap, I rewrote the bw.write to this

bw.Write(i);

解决方案

First of all, you run out of memory because you accumulate data in the MemoryStream, instead of writing it directly to the FileStream. Use the FileStream directly and you won't need much RAM at all (but you will have to keep the file open).

The amount of physical memory unused is not directly relevant to this exception, as strange as that might sound.

What matters is:

  • that you have a contiguous chunk of memory available in the process' virtual address space
  • that the system commit does not exceed the total RAM size + page file size

When you ask the Windows memory manager to allocate you some RAM, it needs to check not how much is available, but how much it has promised to make available to every other process. Such promising is done through commits. To commit some memory means that the memory manager offered you a guarantee that it will be available when you finally make use of it.

So, it can be that the physical RAM is completely used up, but your allocation request still succeeds. Why? Because there is lots of space available in the page file. When you actually start using the RAM you got through such an allocation, the memory manager will just simply page out something else. So 0 physical RAM != allocations will fail.

The opposite can happen too; an allocation can fail despite having some unused physical RAM. Your process sees memory through the so-called virtual address space. When your process reads memory at address 0x12340000, that's a virtual address. It might map to RAM at 0x78650000, or at 0x000000AB12340000 (running a 32-bit process on a 64-bit OS), it might point to something that only exists in the page file, or it might not even point at anything at all.

When you want to allocate a block of memory with contiguous addresses, it's in this virtual address space that the RAM needs to be contiguous. For a 32-bit process, you only get 2GB or 3GB of usable address space, so it's not too hard to use it up in such a way that no contiguous chunk of a sufficient size exists, despite there being both free physical RAM and enough total unused virtual address space.

这篇关于为什么我得到的System.OutOfMemoryException即使有关于RAM 700MB免费的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆