从数据库中取出要准备处理的数据大约5000件到10000件左右。
然后循环处理这里数据:
for ...   ...
   通过上面取得的数据,再到数据库取数据做更新或登陆处理。
   ...next ...数据取出,更新,登录全部用DataSet来做处理。现在的问题是,如果实行上面的处理内存会一直上涨,知道处理完毕才会落下来。
循环中DataSet也做了Dispose,也不好用。
请问问题出在哪里,怎样能将内存释放掉?请大家指教。

解决方案 »

  1.   

    别用DataSet。DataSet比较耗内存。Dispose并不是立即释放的,而只是通知GC在GC认为“合适的时候”释放。
    欢迎大家来我的博客作客:http://blog.csdn.net/aafshzj/
    我正在写一系列关于AAF组件框架的文章。该框架能对开发工作提供很多帮助,并极大地提高开发效率。希望大家看一看并提出宝贵建议。
      

  2.   

    读用IDataReader,写就用Command自己写SQL语句实现。
      

  3.   

    请教除了Dispose有没有别的办法能释放掉的?
    现在都是最后测试阶段了,没时间修改程序了。PS:aafshzj    
    GC是什么意思啊?
      

  4.   

    同意vosov(ask a favor of wind...) 的
      

  5.   

    用dataset相当于把所有要处理的数据都放到内存中了,只有当你不用这个dataset的时候,才能释放内存
    如果这些数据没有什么关联性,可以使用datareader,每次读一条,修改,写回数据库。可以降低内存使用量,但是速度可能会慢。
      

  6.   

    谢谢大家的帮忙,不过使用了vosov(ask a favor of wind...)的方法后,内存还是一直在涨,
    也许可能其它的地方也耗内存。
    再次请教大家,除了Dataset比较消耗内存外,还有什么处理比较好内存的,有什么办法解决呢?
      

  7.   

    频繁地调用GC.Collect();本身就会影响性能。
      

  8.   

    ls都有人说了...GC只会在"需要的时候"才释放内存...
    所以服务器跟个人电脑的内存使用策略应该是不一样的...
      

  9.   

    如果内存很多而当前任务很密集,GC一般是不会释放内存的,直到内存接近某个threshhold或者处理器比较空闲。所以只要你确定你的带脉没有内存泄露就可以了,除非你的内存很容易就攀升到G的规模。
      

  10.   

    2G的内存,估计运行3,4个小时候后就会达到1.2G。顺便再问一下,关于DataSet的Insert处理。
    sqlDataAdapter自动生成Insert语句里面有SELECT(见例),这样会不会影响速度?
    把SELECT去掉的话会有什么影响?例:
    INSERT INTO 送達確認(電文ID,...) VALUES (@電文ID, ...); SELECT 電文ID, ... FROM 送達確認 WHERE (電文ID = @電文ID)', N'@電文ID varchar(12,...)
      

  11.   

    还是那句话,频繁使用的页面和性能敏感的代码中不要使用dataset.
      

  12.   

    sigh看你用的是 SqlClient,说明是 SQL Server
    ok,有几个方面可以优化,但请注意以下细节,并根据自己的实际情况做出判断:1、如果使用 SqlDataReader 来读取外循环所需要的数据,最好独立使用一个 SqlConnection,因为 SqlDataReader 的特点是 调用一次 Read() 方法去数据库读一条——看清楚了,外循环数量特别巨大的时候,这个连接一直是开着的。
    所以,在你的例子中(因为信息不够也许不准确),我推荐你继续使用 DataSet/DataTable 来取出外循环所需的数据,取出后数据已经与服务器没有关系,此时可以断开数据库连接:调用SqlConnection.Close() 方法既可2、循环中对数据库进行的操作,尽可能使用 SqlCommand 的 ExecuteNoQery()——例如 Update 和 Insert,并且不必考虑 SqlConnection 的释放——没有必要循环一次就 new 一个 SqlConnection 吧?3、事实上,你的应用很可能直接可以使用一个复杂的 SQL 语句解决,比如嵌套的 Update 或 Insert Into 即可,那样性能会更好——因为不必在数据库与程序之间来回多次,减少 RoundTrip4、另外的角度来说,因为不鼓励使用游标,那么循环内的操作完全可以改为使用存储过程来优化,这样的话虽然达不到 3 的理想效果,但已经能很大程度减少 RoundTrip 了5、楼上几位说到释放连接对象资源的时候都是胡扯,要认真补补基本功了:
    使用连接对象完毕后,仅仅调用SqlConnection.Close() 方法即可——此时连接对象资源会被自动交还给 连接池——ADO.NET 自己会维护,不必你操心。如果调用 Dispose() 的后果是一旦连接对象被 GC 收回,那么连接池中始终没有可以用来复用的连接对象,也就失去了使用连接池的意义——因为申请新的连接对象的时候,池中没有连接对象可用,于是又要重新与数据库服务器连接、安全性验证、登录验证...很浪费资源(内存/CPU/网络)。如果又没有调用 Close() 又没有使用 Dispose(),好家伙,那你的连接池很快就会满了——直到你的连接对象因为应用程序退出或者 GC 收集的时候才会真正释放,那么很快就会抛出异常:已经到达连接池最大缓存大小——显然本例中不是这样的至于 GC 的部分,楼上各位说的倒是正确,可惜对于数据库连接池的理解谬之千里。不知道如此优化会对你的应用带来多大效果(根据具体情况再看看),但至少按照楼上各位的思路去解决,必死无疑。
      

  13.   

    C# & ASP.NET讨论群: 32095860  欢迎有经验的朋友加入