速度越来越慢,内存占用越来越高。关了重开,就又快了。
已知:
1.GC.Collection 毫无用处
2.数据库连接运行一次就关闭一次,所以应该不是数据库连接造成的。
3.我的程序里有用到 ref 类型的结构体数组,长度30000
4.我比较笨,Dispose()不会用,依样画葫芦写了   
       public void Dispose()
        { 
            GC.SuppressFinalize(this);
        }
没有效果。求分析,另外求Dispose的正确用法,最好和那个万精油例子不一样

解决方案 »

  1.   

     GC.SuppressFinalize()方法的说明你看过吗?
    另外,代码贴全一点。
      

  2.   

    你能贴出更多的代码吗? 并且你可以看看MSDN中垃圾回收或者Clr Via C#垃圾回收的章节
      

  3.   

    Dispose用来释放非托管资源,我不管你什么万精油,总之你拿它代替GC本身就是风马牛不相及。
      

  4.   

    你可以用profile分析下内存使用情况:
    选analyze -> launch performance wizard, 选“.NET memory allocation”
    一般内存增长多数因为非托管资源没有释放。
      

  5.   

    另外,WebBrowser这种东西最好别用。
      

  6.   

    楼主,你说的这么简单,别人怎么帮你分析?如果是占用内存越来越大肯定是有挂起的死循环。只要是没有死循环的对象,GC肯定会回收的,只是时间的问题。如果不涉及非托管资源的释放,最好还是不要去手动调用GC。
      

  7.   

    不是偷懒不贴代码,实在是没法贴,贴出来也没意义,我调用的时候写出来的代码只有三行,其他的都封装成DLL了,每个DLL里面都是几百行代码。另外,应该没有什么非托管资源,唯一就有一个数据库连接,但是每运行一次都已经在finally{}那里关闭了。
      

  8.   

    看过,只是不太理解dispose() 那个万金油例子。
    protected virtual void Dispose(bool disposing)
            {
                // Check to see if Dispose has already been called.
                if(!this.disposed)
                {
                    // If disposing equals true, dispose all managed
                    // and unmanaged resources.
                    if(disposing)
                    {
                        // Dispose managed resources.
                        component.Dispose();
                    }                // Call the appropriate methods to clean up
                    // unmanaged resources here.
                    // If disposing is false,
                    // only the following code is executed.
                    CloseHandle(handle);
                    handle = IntPtr.Zero;                // Note disposing has been done.
                    disposed = true;            }
            }如果里面有我自己定义对象的实例该怎么销毁?设为null?
      

  9.   

    那应该很正常,.net程序都是这样的。
    没有非托管资源的话,不用去操心dispose。
    你再用profile看看,这次选instrumentation,看程序慢在什么地方。
      

  10.   

     private void btnStart_Click(object sender, EventArgs e)
            {             int a = System.Environment.TickCount;
                 list = DBConection.GetGPSPoints.GetPointList(2013, 7, 15, 18, 40, 20);//读取数据库
                 NearestCalBatchPoint testpro = new NearestCalBatchPoint();//实例化            
                 testpro.BatchPointsCal(@"F:\test\nc\SHP\TEST_1.shp", ref list, (double)30 / 33 / 3600);//地图运算
                 b = System.Environment.TickCount - a;
                 MessageBox.Show("Computation Time" + b.ToString());
            }
    public class NearestCalBatchPoint    
    {
            public  string fileName = null;
            public  List<DBConection.GetGPSPoints.GPSPoint> list=null;
            public  NearestPointToLine nearestPointToLine = new NearestPointToLine();
            public  IFeatureClass featureClass;
            
    public void BatchPointsCal(string filenameInput, ref List<DBConection.GetGPSPoints.GPSPoint> listInput, double delta)
            {
                    fileName = filenameInput;
                    list = listInput;
                    featureClass = nearestPointToLine.ReadShapefile(fileName);
                    for (int i = 0; i < list.Count; i++)
                    {
                        nearestPointToLine.NearestLineAttribute_Fast(featureClass, list[i].lat, list[i].lon, delta, ref list, i);
                    }
                                    System.Runtime.InteropServices.Marshal.ReleaseComObject(featureClass);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(nearestPointToLine.featureCursor);
                }
    }
      

  11.   

    那应该很正常,.net程序都是这样的。
    没有非托管资源的话,不用去操心dispose。
    你再用profile看看,这次选instrumentation,看程序慢在什么地方。
    谢谢,我再看看
    现在的内存和时间消耗有点让我哭笑不得,因为是个自动运行的后台程序,必须要在3分钟之内算完。
    现在运算10次的时间消耗是
    50秒---80秒---90秒---120秒---100秒---90秒---80秒---50秒---80秒---100秒。跨度都2倍了,有些蛋疼,这是不是GC没有及时回收造成的?我的数据量是有点大的
      

  12.   

    你都调用了com组件怎么还说没有用到非托管资源,八成是com资源没有释放
      

  13.   

    你调用了com了,具体花多少时间就不完全你说了算了,
    当你调用com的一些方法时,还要看这个com的宿主程序的处理,处理完了才会返回(同步执行)
    如果那个程序本身就很忙了,你还在调用,慢就是自然的事情了
    你可以用多线程去控制,如果3分钟之后,仍然还有活动的线程(没有处理完的),提示系统忙之类的...
      

  14.   


    可是监视内存的时候又是忽高忽低的。如果要释放,用dispose();起关键性作用的是GC.SuppressFinalize(this)吗?网上的那个例子我看得不是很明白,是不是使用GC.SuppressFinalize(this)之前要把那些变量和实例都设置成null?
      

  15.   


    调用的ESRI组件不支持多线程
      

  16.   

    想办法把你的程序改造成只new一个NearestCalBatchPoint,每次调用都用这个实例,程序结束时再释放,不要每次都去new
      

  17.   

    .net的CG有的时候偶尔不听话,不过其实99%是代码的问题~~
      

  18.   

    自己继承IDispose接口,在重写Dispose方法
    public void Dispose()
    {
    //释放托管资源代码
    //释放非托管资源代码
    }
    每次实例化该类的时候using(),这样一般不会有什么问题
      

  19.   

    看撸主代码,主要也就是
    list = DBConection.GetGPSPoints.GetPointList(2013, 7, 15, 18, 40, 20);//读取数据库              NearestCalBatchPoint testpro = new NearestCalBatchPoint();//实例化                          testpro.BatchPointsCal(@"F:\test\nc\SHP\TEST_1.shp", ref list, (double)30 / 33 / 3600);//地图运算
    这三行吧,可以每行之间加一个log或者计时,就知道哪里耗时最多吧。
    不要不知道问题出在哪里就认为是没有GC。
      

  20.   

    3.ref 类型的结构体数组? 指向一个结构体的指针,然后是30000字节,结构体是值类型,在栈上分配内存空间,我觉得问题出在这个结构体数组上,轻量级的对象用结构,数据量大或者有复杂处理逻辑的对象最好用类。
    4.隐式Dispose()调用Dispose(true)然后调用GC.SuppressFinalize(this),前面带参数ture的dispose函数已经释放了托管和非托管的内存,后面这个GC.SuppressFinalize(this),是为了防止垃圾回收器对不需要终止的对象调用Object.Finalize.因为你已经显示的调用了Dispose(true)了。我给你复制一段MSDN的话,我觉得对你可以能有帮助。
     当类型使用文件句柄或数据库连接这类在回收使用托管对象时必须释放的非托管资源时,该类型必须实现 Finalize。有关辅助和具有更多控制的资源处置方式,请参见 IDisposable 接口。 Finalize 可以采取任何操作,包括在垃圾回收过程中清理了对象后使对象复活(即,使对象再次可访问)。但是,对象只能复活一次;在垃圾回收过程中,不能对复活对象调用 Finalize。