Raz*_*t4x 5 c# out-of-memory winforms
我正在运行一些测试,看看我的日志记录将如何执行而不是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));
}
}
Run Code Online (Sandbox Code Playgroud)
当i达到25413324我得到了Exception of type 'System.OutOfMemoryException' was thrown.,即使我的Process Explorer的说,我对自由的RAM 700MB ???
这是屏幕截图(以防万一)
Process Explorer

这是winform

编辑:为了在堆上创建更多对象,我重写了bw.write这个
bw.Write(i);
Run Code Online (Sandbox Code Playgroud)
首先,由于您在数据中累积数据MemoryStream而不是直接将数据写入数据库,因此内存不足FileStream.FileStream直接使用,你根本不需要太多的RAM(但你必须保持文件打开).
未使用的物理内存量与此异常没有直接关系,这听起来很奇怪.
重要的是:
当您要求Windows内存管理器为您分配一些RAM时,它需要检查可用的数量,以及它承诺为每个其他进程提供多少内存.这样的承诺是通过提交来完成的.要提交一些存储空间是指内存管理器提供您一个保证,这将是可用的,当你终于利用它.
因此,可能是物理RAM已完全耗尽,但您的分配请求仍然成功.为什么?因为页面文件中有很多可用空间.当你真正开始使用RAM时,通过这样的分配,内存管理器只会简单地分页.所以0物理RAM!=分配将失败.
相反的情况也可能发生; 尽管有一些未使用的物理RAM,分配仍会失败.您的进程通过所谓的虚拟地址空间查看内存.当您的进程在地址处读取内存时0x12340000,这是一个虚拟地址.它可能映射到RAM 0x78650000或在0x000000AB12340000(在64位操作系统上运行32位进程)的RAM ,它可能指向仅存在于页面文件中的东西,或者它甚至可能根本不指向任何东西.
如果要分配具有连续地址的内存块,则在此虚拟地址空间中RAM需要是连续的.对于32位进程,您只能获得2GB或3GB的可用地址空间,因此尽管存在可用的物理RAM和足够的空间,但是使用它并不太难以存在足够大小的连续块.总未使用的虚拟地址空间.
| 归档时间: |
|
| 查看次数: |
6273 次 |
| 最近记录: |