C# 减少文件操作的内存占用

C# 减少文件操作的内存占用,c#,file-io,memory-leaks,out-of-memory,C#,File Io,Memory Leaks,Out Of Memory,我正在尝试运行此方法,它工作正常,但每次经过数百次内部迭代后,我都会遇到内存不足异常: ... MNDBEntities db = new MNDBEntities(); var regs = new List<DOCUMENTS>(); var query = from reg in db.DOCUMENTS where reg.TAG_KEYS.Any(p => p.TAG_DATE_VALUES.FirstOrDefault().TAG_DATE_

我正在尝试运行此方法,它工作正常,但每次经过数百次内部迭代后,我都会遇到内存不足异常:

...
MNDBEntities db = new MNDBEntities();
var regs = new List<DOCUMENTS>();
var query = from reg in db.DOCUMENTS
            where reg.TAG_KEYS.Any(p => p.TAG_DATE_VALUES.FirstOrDefault().TAG_DATE_VALUE.HasValue 
                && p.TAG_DATE_VALUES.FirstOrDefault().TAG_DATE_VALUE.Value.Year == 2012)
            select reg;

var pages = new List<string>();
foreach (var item in query)
{
    Document cert = new Document();

    var tags = item.TAG_KEYS;
    foreach (var tag in tags)
    {
        // Basic stuff...
    }

    var pagesS = item.PAGES;
    foreach (var page in pagesS)
    {
        var path = @"C:\Kumquat\" + (int)page.NUMBER + ".vpimg";
        File.WriteAllBytes(path, page.IMAGE);
        pages.Add(path);
        Console.WriteLine(path);
    }

    //cms.Save(cert, pages.ToArray()).Wait();
    foreach (var pageFile in pages)
        File.Delete(pageFile);

    pagesS = null;
    pages.Clear();
}
...
。。。
MNDBEntities db=新的MNDBEntities();
var regs=新列表();
var query=从db.DOCUMENTS中的注册表
其中reg.TAG\u KEYS.Any(p=>p.TAG\u DATE\u VALUES.FirstOrDefault().TAG\u DATE\u VALUE.HasValue
&&p.TAG_DATE_VALUES.FirstOrDefault().TAG_DATE_VALUE.VALUE.Year==2012)
选择注册表;
var pages=新列表();
foreach(查询中的var项)
{
文档证书=新文档();
var tags=item.TAG\u键;
foreach(标签中的var标签)
{
//基本的东西。。。
}
var pagesS=item.PAGES;
foreach(页面中的变量页)
{
变量路径=@“C:\Kumquat\”+(int)page.NUMBER+“.vpimg”;
File.writealBytes(路径,page.IMAGE);
pages.Add(路径);
控制台写入线(路径);
}
//cms.Save(cert,pages.ToArray()).Wait();
foreach(页面中的var pageFile)
文件。删除(页面文件);
pagesS=null;
pages.Clear();
}
...
我很确定问题与File.writealBytes或File.Delete有关,因为如果我对这些行进行注释,该方法将毫无例外地运行。我所做的基本上是从数据库和文档图像中获取一些标记,然后将这些图像保存到磁盘上,然后存储到cms中,然后从磁盘中删除。老实说,我不知道我在那个文件调用上做错了什么。有什么想法吗

这是PerfView显示的内容:

这就是visual studio 2012 profiler显示为热点的内容,问题是:这都是生成的代码(在实体模型中)我是否在模型的属性上做错了什么

尝试使用来评测代码,重点关注GC事件和CLR管理的分配勾选事件

page.IMAGE可能是问题所在。它很可能会分配一个字节数组,而不会删除它。最好将代码更改为:

page.WriteTo(path);

显示的其余代码看起来不错。唯一可能的问题是大对象分配,这可能导致中的碎片问题。

您的
db
应该在
中使用
,是吗?这里还有其他的
IDisposable
类吗?可能是
文档
?查询返回的记录大概有多少,每个记录的
图像
有多大?如果您在
写字节
中发现漏洞,我会感到惊讶,
文件。删除
几乎不分配内存(可以这么说)。您需要了解如何实例化数据,并可能实现某种处理模式,以确保不会耗尽内存。但是,如果不知道“cms”是什么,也不知道您从数据库中提取的数据类型,就很难推荐特定的内容。可能是一个具有IDisposable接口的对象,该对象未正确处理。Concider将foreach的内部主体封装到一个“using”中,或者在继续通过loop@Blorgbeard对它被一个包裹着。Document是一个普通的类,不是一次性的(只有几个字符串变量)。Feng Page.IMAGE是一个字节[],没有Page.WriteTo,这正是File.writealBytes(path,Page.IMAGE)所要的;他正在做什么。我会尝试你建议的工具,并将张贴。经过相当艰苦的工作,你是对的。这是一个与大字节数组(在LOH中)的实例创建相关的问题。我更改了code属性,删除了嵌套的实体框架代码,并将其替换为自定义本机SQL。对于最初的否决票,我很抱歉,我不理解您在开始时的反应+1并接受。多谢各位。