Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中处理大文件时出现内存不足异常_C#_.net_Winforms_Visual Studio 2010_List - Fatal编程技术网

C# 在C中处理大文件时出现内存不足异常

C# 在C中处理大文件时出现内存不足异常,c#,.net,winforms,visual-studio-2010,list,C#,.net,Winforms,Visual Studio 2010,List,我有一个WinC窗体应用程序,其中使用 OpenFileDialog允许用户选择要打开的文本文件。允许多选 一旦他们选择了文本文件,我就通过List.Add操作逐个打开文件,获取文本并将内容存储在列表变量中 我的问题发生在用户选择了大量的文本文件时,比如1264个文本文件,总大小高达750MB,程序无法处理它。它最多读取850个文件,然后给我一个内存不足异常。 在TaskManager中,发生这种情况时,应用程序的memoryprivate工作集大约为1.5GB。 我使用带有32GB ram的x

我有一个WinC窗体应用程序,其中使用 OpenFileDialog允许用户选择要打开的文本文件。允许多选 一旦他们选择了文本文件,我就通过List.Add操作逐个打开文件,获取文本并将内容存储在列表变量中

我的问题发生在用户选择了大量的文本文件时,比如1264个文本文件,总大小高达750MB,程序无法处理它。它最多读取850个文件,然后给我一个内存不足异常。 在TaskManager中,发生这种情况时,应用程序的memoryprivate工作集大约为1.5GB。 我使用带有32GB ram的x64机器

我给出的代码可以读取文件:

public static List<LoadData> LoadDataFromFile(string[] filenames)
{
    List<LoadData> MasterData = new List<LoadData>();
    lookingForJobs = new LookingForJobs(1,filenames.Length);
    lookingForJobs.Show();
    /*-------OUTER LOOP TO GO THROUGH ALL THE FILES-------*/
    for (int index = 0; index < filenames.Length; index++)
    {
        string path = filenames[index];
        /*----------INNER LOOP TO GO THROUGH THE CONTENTS OF EACH FILE------*/
        foreach (string line in File.ReadAllLines(path))
        {
            string[] columns = line.Split('\t');
            if (columns.Length == 9)
            {
                if (line.StartsWith("<"))    /*-------IGNORING THE FIRST 8 LINES OF EACH LOG FILE CONTAINING THE LOGGER INFO---------*/
                {
                    MasterData.Add(new LoadData
                    {
                        Event_Type = columns[0],
                        Timestamp = columns[1],
                        Log_Message = columns[2],
                        Category = columns[3],
                        User = columns[4],
                        Thread_ID = columns[5],
                        Error_Code = columns[6],
                        Application = columns[7],
                        Machine = columns[8]
                    });
                }
            }
        }
        lookingForJobs.SearchingForJobsProgress.PerformStep();
        /*--------END OF INNER LOOP--------*/
    }
    lookingForJobs.Dispose();
    /*-----------END OF OUTER LOOP-----*/
    return MasterData;
}
编辑: 我知道我应该重新设计我的代码,这样就不会同时将所有文件读入对象。但是,我想知道列表对象或memoryprivate工作集的大小是否有任何限制。我在几篇文章中读到,有时当您达到1.5-1.6 GB时,会出现此类问题。

使用File.ReadLines而不是File.ReadAllLines,因为第二行不必要地将所有文件加载到内存中,而您一次只需要一行:

使用ReadAllLines时,必须等待返回整个字符串数组,然后才能访问该数组。因此,当您处理非常大的文件时,ReadLines会更加高效

这可能会给您带来很大的内存改进


第二个想法是重新思考你是否真的需要如此大的数据存储在内存中。也许您可以只存储每个文件的文件路径,并根据需要读取它们。

您的文件可能很小,但您正在构建的MasterData对象仍将存储它在内存中找到的所有数据

听起来您可能需要重新设计一些应用程序


您是否通过探查器运行了此操作?查看是否可以在整个程序过程中检查内存使用情况?

您正在创建包含从文件中读取的大部分数据的对象。我认为类别、用户、错误代码、应用程序和机器的值将在许多记录中重复

您可以制作一个包含这些字符串值的字典。对于您读取的每个值,您将检查字典中是否已经存在相等的字符串,并使用该字符串,否则将其添加。这样,这些字符串在内存中只存在一次

字符串插入使用相同的原理,但如果您插入字符串,它们将保留在内存中,直到应用程序关闭。把它们放在字典里,你就可以在不再需要它们的时候把它们删除

榜样;编一本字典:

Dictionary<string, string> values = new Dictionary<string, string>();
string category = columns[3];
if (values.ContainsKey(category)) {
  category = values[category];
} else {
  values.Add(category, category);
}

当然,您只会在希望有大量重复值的值上使用此选项。

您是在x64模式下构建应用程序吗?@Guffa添加内存直到它崩溃不一定是正确的修复方法,特别是当流式而非缓冲式方法非常简单时,请参见Konrad的回答您确定需要将所有数据同时存储在内存中吗@MarcGravel:由于每个文件处理后都会扔掉这些数据,我无法想象这会造成如此大的差异。@Simon,是的,也许我可以选择一种方法,在处理完数据后删除一些数据。我的主数据列表大小高达2564543个元素。这里有什么限制吗?有时候,一个看起来微不足道的改变是如此的有效。是的,我改变了它,同样的问题也发生了。单个文件不是很大,每个文件大小为650KB。因为每个文件处理后都会丢弃这些数据,所以不会有太大的区别。@KonradKokosa:必须为任一解决方案创建所有字符串对象,因此,与内存管理视图没有太大区别。至少有两种可能性:1使用x64,假设单个元素的数量不超过2^31;2将主数据写入文件,然后一次处理一个记录。这是一个我从未想到的有趣的优化。如果实现,将大大减少内存。谢谢