从数据库中取出要准备处理的数据大约5000件到10000件左右。
然后循环处理这里数据:
for ... ...
通过上面取得的数据,再到数据库取数据做更新或登陆处理。
...next ...数据取出,更新,登录全部用DataSet来做处理。现在的问题是,如果实行上面的处理内存会一直上涨,知道处理完毕才会落下来。
循环中DataSet也做了Dispose,也不好用。
请问问题出在哪里,怎样能将内存释放掉?请大家指教。
然后循环处理这里数据:
for ... ...
通过上面取得的数据,再到数据库取数据做更新或登陆处理。
...next ...数据取出,更新,登录全部用DataSet来做处理。现在的问题是,如果实行上面的处理内存会一直上涨,知道处理完毕才会落下来。
循环中DataSet也做了Dispose,也不好用。
请问问题出在哪里,怎样能将内存释放掉?请大家指教。
欢迎大家来我的博客作客:http://blog.csdn.net/aafshzj/
我正在写一系列关于AAF组件框架的文章。该框架能对开发工作提供很多帮助,并极大地提高开发效率。希望大家看一看并提出宝贵建议。
现在都是最后测试阶段了,没时间修改程序了。PS:aafshzj
GC是什么意思啊?
如果这些数据没有什么关联性,可以使用datareader,每次读一条,修改,写回数据库。可以降低内存使用量,但是速度可能会慢。
也许可能其它的地方也耗内存。
再次请教大家,除了Dataset比较消耗内存外,还有什么处理比较好内存的,有什么办法解决呢?
所以服务器跟个人电脑的内存使用策略应该是不一样的...
sqlDataAdapter自动生成Insert语句里面有SELECT(见例),这样会不会影响速度?
把SELECT去掉的话会有什么影响?例:
INSERT INTO 送達確認(電文ID,...) VALUES (@電文ID, ...); SELECT 電文ID, ... FROM 送達確認 WHERE (電文ID = @電文ID)', N'@電文ID varchar(12,...)
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 的部分,楼上各位说的倒是正确,可惜对于数据库连接池的理解谬之千里。不知道如此优化会对你的应用带来多大效果(根据具体情况再看看),但至少按照楼上各位的思路去解决,必死无疑。