高内存使用问题

时间:2011-09-07 14:35:35

标签: c# wpf memory-management

我创建了一个WPF应用程序,它打开CSV文件并执行一些包含webscrapping的操作,并获取一些类型为long的值。(0-10000000)

现在的问题是,当打开大约2000个大型列表时,软件的内存使用量在某些情况下会增加到700MB以上。

我很震惊地看到这一点。

我认为有些事情是

  1. 如果csv文件的每个条目具有与之关联的长值,则会占用大量内存。单个条目大约有10-12列,每个类型都很长。现在有大量行数记忆射击

  2. 代码中有一些地方有一个循环(在所有csv行上),它创建了一个自定义class.i的实例。想到了析构函数然后才知道dot net会自动管理内存。

  3. 这里有加载CSV的代码

        try
        {
            StreamReader sr = new StreamReader(path,Encoding.Default);
            labelRankCheckStatus.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
            {
                labelRankCheckStatus.Content = "Loading Data";
            }));
    
            string strline = "";
            string[] _values = null;
            int x = 0;
    
            while (!sr.EndOfStream)
            {
                x++;
                strline = sr.ReadLine();
                _values = strline.Split(',');
                if (x == 1)
                {
                    textBoxKw1.Text = _values[12];
                    textBoxKw2.Text = _values[14];
                    textBoxKw3.Text = _values[16];
                    textBoxKw4.Text = _values[18];
                }
                else if (x != 1)
                {
                    if (_values[0] != "")
                    {
                        Url info = new Url();
                        srNo++;
                        info.URL = idn.GetAscii(_values[0].ToString().Trim()); 
                        info.IsChecked = true;
    
                        info.TestResults = int.Parse(_values[1].Replace("%","").TrimEnd().TrimStart());
    
                        info.PageRank= int.Parse(_values[2]);
                        info.RelPageRank = int.Parse(_values[3].Replace("%","").TrimEnd().TrimStart());
    
                        info.Alexa= long.Parse(_values[4]);
                        info.RelAlexa = long.Parse(_values[5].Replace("%","").TrimEnd().TrimStart());
    
                        info.Links= long.Parse(_values[6]);
                        info.RelLinks = long.Parse(_values[7].Replace("%","").TrimEnd().TrimStart());
    
                        info.GIW= long.Parse(_values[8]);
                        info.RelGIW = long.Parse(_values[9].Replace("%","").TrimEnd().TrimStart());
    
                        info.GIN= long.Parse(_values[10]);
                        info.RelGIN = long.Parse(_values[11].Replace("%","").TrimEnd().TrimStart());
    
                        info.Kw1Indexed= long.Parse(_values[12]);
                        info.RelKw1Indexed = long.Parse(_values[13].Replace("%","").TrimEnd().TrimStart());
    
                        info.Kw2Indexed= long.Parse(_values[14]);
                        info.RelKw2Indexed = long.Parse(_values[15].Replace("%","").TrimEnd().TrimStart());
    
                        info.Kw3Indexed= long.Parse(_values[16]);
                        info.RelKw3Indexed = long.Parse(_values[17].Replace("%","").TrimEnd().TrimStart());
    
                        info.Kw4Indexed= long.Parse(_values[18]);
                        info.RelKw4Indexed = long.Parse(_values[19].Replace("%","").TrimEnd().TrimStart());
    
                        info.DKwIndexed= long.Parse(_values[20]);
                        info.RelDKwIndexed = long.Parse(_values[21].Replace("%","").TrimEnd().TrimStart());
    
                        info.Info= _values[22];
    
                        info.srNo = srNo;
                        url.Add(info);
                    }
    
                }
                dataGrid1.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                {
                    dataGrid1.Columns[2].Header = "URL ( " + url.Count + " )";
    
                    try
                    {
                        if (dataGrid1.ItemsSource == null)
                            dataGrid1.ItemsSource = url;
                        else
                            dataGrid1.Items.Refresh();
                    }
                    catch (Exception)
                    {
                    }
                    labelRankCheckStatus.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                    {
                        labelRankCheckStatus.Content = "Done";
                    }));
                }));
    
            }
            sr.Close();
            labelRankCheckStatus.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
            {
                labelRankCheckStatus.Content = "Complete ";
            }));
        }
        catch (Exception c)
        {
            MessageBox.Show(c.Message);
        }`
    

1 个答案:

答案 0 :(得分:3)

不要构建大型对象的内存副本,而应考虑一种更实用的方法,您可以在其中流式传输数据,处理数据并将其输出到您选择的数据库中。如果需要对旧数据执行操作,可以使用Sqlite之类的SQL数据库。

为系统中的每个实体创建托管对象都是非常浪费的,您不需要大多数托管对象。

当然,如果你有很多内存,可能只是因为GC还没有费心去收集你所有的垃圾,因为任何东西都不需要内存。但是你更有可能持有对它的引用。