我正在运行一些测试,看看我的日志记录将如何执行而不是执行File.AppendAllText
我会首先写入内存流,然后复制到文件。所以,只是为了看看内存操作有多快,我这样做了..
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
到达25413324
我有一个Exception of type 'System.OutOfMemoryException' was thrown.
即使我的流程浏览器 http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx说我有大约 700Mb 的可用内存???
这是屏幕截图(以防万一)
Process Explorer
这是winform
EDIT :为了在堆上创建更多对象,我重写了bw.write
to this
bw.Write(i);
首先,你会耗尽内存,因为你在MemoryStream
,而不是直接将其写入FileStream
。使用FileStream
直接,你根本不需要太多内存(但你必须保持文件打开)。
未使用的物理内存量与此异常没有直接关系,这听起来很奇怪。
重要的是:
- 进程中有一块连续的可用内存'虚拟地址空间
- 系统提交不超过总 RAM 大小 + 页面文件大小
当您要求 Windows 内存管理器为您分配一些 RAM 时,它需要检查的不是多少可用的,但是它有多少promised供所有其他进程使用。这种承诺是通过提交来完成的。到commit一些内存意味着内存管理器向您保证它will当您最终使用它时即可使用。
因此,物理 RAM 可能已完全用完,但您的分配请求仍然成功。为什么?因为页面文件中有大量可用空间。当您实际开始使用通过此类分配获得的 RAM 时,内存管理器只会简单地调出其他内容。因此 0 物理 RAM != 分配将会失败。
相反的情况也可能发生。尽管有一些未使用的物理 RAM,分配也可能会失败。你的进程通过所谓的虚拟地址空间。当您的进程读取地址处的内存时0x12340000
,这是一个虚拟地址。它可能映射到 RAM0x78650000
, or at 0x000000AB12340000
(在 64 位操作系统上运行 32 位进程),它可能指向仅存在于页面文件中的内容,或者甚至可能根本不指向任何内容。
当您想要分配具有连续地址的内存块时,RAM 需要在该虚拟地址空间中是连续的。对于 32 位进程,您只能获得 2GB 或 3GB 的可用地址空间,因此以不存在足够大小的连续块的方式使用它并不太难,尽管有可用的物理 RAM 和足够的内存未使用的虚拟地址空间总量。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)