zoukankan      html  css  js  c++  java
  • 第一次通过CLR Profile解决内存占用过高的问题

    炮哥:"嘿,哥们,忙啥呢,电脑卡成这逼样。"

    勇哥:"在用CLR Profile工具分析下FlexiPrint的内存占用情况。"

    炮哥:“哎哟,不错啊,玩高级的了。”

    勇哥:“也没有啊,就是发现点击查询按钮查询数据时,如果数据量一大的话,内存上上升了好几个M,所以第一感觉就不太正常。正好以前也了解过CLR Profile,但一直没怎么具休的用过,这次正好拿来研究研究。”

    炮哥:“Nice job,要向你学习,能够主动发现问题并研究解决方法。对了,有什么发现么?”

    勇哥:“通过工具发现dgMain_CellFormatting方法占用内存过多。”

    炮哥:“这个方法干嘛用的,要这么多的内存?”

    勇哥:“其实做的事情很简单,根据每行订单的不同状态,显示不同的图标,以便让客户能够很直白的了解订单的状态。”

    炮哥:“噢,是这样,那确实没什么,让我看下代码。”

    namespace IPP_PCL.HomeViewUserControl
    {
        public partial class PrintOrderInformationUserControl : UserControl, IHomePrintOrderInformationView
        {
            #region Field
    
            private readonly PrintCellLiteServiceClient _serviceClient = new PrintCellLiteServiceClient();
    
            #endregion
    
            #region Event Handler
    
            /// <summary>
            /// 此事件主要用于图片按钮的显示
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void dgMain_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
            {
                if (dgMain.Columns[e.ColumnIndex].Name.Equals("dgMain_PrintIcon"))
                {
                    int row = e.RowIndex;
                    //获取展示图片按钮的单元格
                    string status = dgMain.Rows[row].Cells["dgMain_statusKey"].Value.ToString();
    
                    switch (status)
                    {
                        case "Print in Progress":
                            string erpSoNumber = this.dgMain.Rows[row].Cells["dgMain_ErpSoNumber"].Value.ToString();
    
                            //从DB中查找erp_so_number的记录
                            IEnumerable<FileIndexModel> fileIndexes = _serviceClient.GetFileIndex(erpSoNumber);
    
                            //如果在FileIndex表中存在pro的记录
                            if (fileIndexes == null || !fileIndexes.Any()) { break; }
    
                            FileIndexModel fileIndex = fileIndexes.First();
    
                            if (FileStatus.PRINTED != fileIndex.PrintedStatus && FileStatus.PARTIAL_PRINTED != fileIndex.PrintedStatus)
                            {
                                e.Value = Properties.Resources.picYellow;
                            }
                            else
                            {
                                e.Value = Properties.Resources.picGreen;
                            }
    
                            break;
    
                        case "Printed":
    
                            e.Value = Properties.Resources.picGreen;
                            break;
    
                        case "Partial Printed":
    
                            e.Value = Properties.Resources.picGreen;
                            break;
    
                        default:
    
                            e.Value = Properties.Resources.picYellow;
                            break;
                    }
                }
            }
    
            #endregion
    
        }
    }

    勇哥:“......”

    炮哥:“很简单,写得很明白,这方法没什么问题吧,会不会搞错了。”

    勇哥:“应该不会,通过CLR Profile分析发现,在这个方法中创建了非常多的对象。”

    炮哥:“你是说BitMap对象?”

    勇哥:“是的。”

    炮哥:“噢,明白了,每次访问Properties.Resources.picGreen类似的属性时,都会创建一个新的对象。但其实图标就那么几类,完全可以先保存在内存中,要用时直接引用就行了。”

    勇哥:“说得对,让我修改下代码 ,看看情况。”

    炮哥:“让我看下你怎么修改的?”

    勇哥:“......”

     1 namespace IPP_PCL.HomeViewUserControl
     2 {
     3     public partial class PrintOrderInformationUserControl : UserControl, IHomePrintOrderInformationView
     4     {
     5         #region Field
     6 
     7         private readonly PrintCellLiteServiceClient _serviceClient = new PrintCellLiteServiceClient();
     8 
     9         Bitmap picGreenBitMap = Properties.Resources.picGreen;
    10 
    11         Bitmap picYellowBitMap = Properties.Resources.picYellow;
    12 
    13         #endregion
    14 
    15         #region Ctor
    16 
    17         public PrintOrderInformationUserControl()
    18         {
    19             InitializeComponent();
    20         }
    21 
    22         #endregion
    23 
    24         #region Event Handler
    25 
    26         /// <summary>
    27         /// 此事件主要用于图片按钮的显示
    28         /// </summary>
    29         /// <param name="sender"></param>
    30         /// <param name="e"></param>
    31         private void dgMain_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    32         {
    33             if (dgMain.Columns[e.ColumnIndex].Name.Equals("dgMain_PrintIcon"))
    34             {
    35                 int row = e.RowIndex;
    36                 //获取展示图片按钮的单元格
    37                 string status = dgMain.Rows[row].Cells["dgMain_statusKey"].Value.ToString();
    38 
    39                 switch (status)
    40                 {
    41                     case "Print in Progress":
    42 
    43                         var proDt = dgMain.DataSource as DataTable;
    44 
    45                         if (proDt == null || proDt.Rows.Count == 0) { break; }
    46 
    47                         string erpSoNumber = this.dgMain.Rows[row].Cells["dgMain_ErpSoNumber"].Value.ToString();
    48 
    49                         //从DB中查找erp_so_number的记录
    50                         IEnumerable<FileIndexModel> fileIndexes = _serviceClient.GetFileIndex(erpSoNumber);
    51 
    52                         //如果在FileIndex表中存在pro的记录
    53                         if (fileIndexes == null || !fileIndexes.Any()) { break; }
    54 
    55                         FileIndexModel fileIndex = fileIndexes.First();
    56 
    57                         if (FileStatus.PRINTED != fileIndex.PrintedStatus && FileStatus.PARTIAL_PRINTED != fileIndex.PrintedStatus)
    58                         {
    59                             e.Value = picYellowBitMap;
    60                         }
    61                         else
    62                         {
    63                             e.Value = picGreenBitMap;
    64                         }
    65 
    66                         break;
    67 
    68                     case "Printed":
    69 
    70                         e.Value = picGreenBitMap;
    71                         break;
    72 
    73                     case "Partial Printed":
    74 
    75                         e.Value = picGreenBitMap;
    76                         break;
    77 
    78                     default:
    79 
    80                         e.Value = picYellowBitMap;
    81                         break;
    82                 }
    83             }
    84         }
    85 
    86         #endregion
    87 
    88     }
    89 }

    炮哥:“再用CLR Profile分析下修改后的内存情况。”

    勇哥:“你看,内存直接从9.0M变为425kB。”

    炮哥:“哈哈,看来问题已经解决了。”

    勇哥:“今天我发现C#也有闭包的概念。”

    炮哥:“闭包?什么玩意?”

    勇哥:“我是在学习JS的时候发现有闭包这个概念,但是没想到C#也有这个。”

    炮哥:“所以说当你视野放开时,你会发现更多的美好。”

    勇哥:“不扯了,该下班了。噢,对了,昨晚看了一部电影<美丽人生>,有兴趣的话可以看下,很不错。”

  • 相关阅读:
    添加日志文件
    C库函数对文件的操作
    getpass的使用
    C语言实现 冒泡排序 选择排序 希尔排序
    批量Ping执行Bash脚本
    Script
    echo
    Centos7 pxe
    Rsync 参数
    Ip HostName查询
  • 原文地址:https://www.cnblogs.com/JustYong/p/5131658.html
Copyright © 2011-2022 走看看