zoukankan      html  css  js  c++  java
  • .Net内存优化的几点经验

      以前从来没有想过.Net开发居然存在内存无法释放的问题,总是认为GC给我处理好了一切。现在GIS二次开发结合三维球开发,没有想到存在如此严重的内存增长,很快内存就不够用了,导致系统各种不稳定。球体和三维模型就开始闪烁,出现无法创建D3D或GDI+设备,OutOfMemory等错误。最近一直为内存优化的事情头疼,虽然优化了部分内容,问题依然没有解决。

      还是总结了一下最近优化的经验:

    1.慎重使用单例,单例会始终保持一个静态对象的引用,内存始终不释放,同时单例类的所有成员变量也不会释放。如单例窗体,解决方法是在Dispose方法中将静态引用置为null。

    2.字符对象使用不当:过多太长字符串,占用大对象堆;同时尽量不使用字符串加,改用StringBuilder

    3.流对象没有关闭。如文件流,网络传输流(HttpResponse,FtpResponse)

    4.坑人的Select * from XX,应该避免使用这种代码,尤其是有Blob字段时候。

    5.读取文件和流时避免new 过大的byte数组,应该分段读取。

    6.事件的挂接。有两种情况:

    A对象作为参数传入B对象,在B对象中为A挂接了事件,如果没有正确移除事件,会导致B对象内存无法回收。例如B为窗体变量,B被Dispose后,内存仍然不会回收。

    A对象通过B的方法获取对象C,而C在B中挂接了事件,此时即使将B设为null,也无法将B对象的实例内存回收。

    7.关于COM,目前项目中大量使用了COM组件,包括DEV、ArcEngine、Slimdx封装的Direct3D、Excel Interop、FlexCell.Net。

      感觉COM,总是内存不释放!不知道怎么回事,即使调用了Marshal.FinalReleaseComObject(),或者Marshal.ReleaseComObject(),感觉RCW的终结器始终没有被调用。ArcEngine在新建图层、删除图层、查询会有显著的内存增长,而且内存第一次明显增长,以后会缓慢增长,增长之后不会释放。

      造成的问题还包括启动读取xls文件的Excel.exe进程无法关闭、WorkspaceFactory占用影像tiff文件,提示文件被另外一个进程占用,无法删除。

      Excel进程关闭可以通过如下的方法解决,在使用完读取写入的方法后调用。

      对于GC.Collect()方法,在确定已经有大量对象被置空时,可以手工调用参考文章

      WorkspaceFactory占用影像tiff文件也可以通过释放RCW来解决,但是内存没有办法释放。

     1       public void Quit()
     2         {
     3             try
     4             {
     5                 _Application.Quit();
     6                 if (_Range != null)
     7                 {
     8                     Marshal.FinalReleaseComObject(_Range);
     9                     _Range = null;
    10                 }
    11                 if (_Worksheet != null)
    12                 {
    13                     Marshal.FinalReleaseComObject(_Worksheet);
    14                     _Worksheet = null;
    15                 }
    16                 if (_Workbook != null)
    17                 {
    18                     Marshal.FinalReleaseComObject(_Workbook);
    19                     _Workbook = null;
    20                 }
    21                 if (_Workbooks != null)
    22                 {
    23                     Marshal.FinalReleaseComObject(_Workbooks);
    24                     _Workbooks = null;
    25                 }
    26                 if (_Application != null)
    27                 {
    28                     Marshal.FinalReleaseComObject(_Application);
    29                     _Application = null;
    30                 }
    31                
    32             }
    33             catch { }
    34             GC.Collect();
    35             GC.WaitForPendingFinalizers();
    36         } 

     希望大家给我点建议。

     

  • 相关阅读:
    POJ 3253 Fence Repair
    POJ 2431 Expedition
    NYOJ 269 VF
    NYOJ 456 邮票分你一半
    划分数问题 DP
    HDU 1253 胜利大逃亡
    NYOJ 294 Bot Trust
    NYOJ 36 最长公共子序列
    HDU 1555 How many days?
    01背包 (大数据)
  • 原文地址:https://www.cnblogs.com/yhlx125/p/4227705.html
Copyright © 2011-2022 走看看