前不久為用戶做了一個小工具,把數(shù)據(jù)中心的數(shù)據(jù)發(fā)布到其它相應的數(shù)據(jù)庫.到用戶的測試機上一跑,
10分鐘左右,內(nèi)存用光(1.5G)
,跟蹤看了一下
IBATISN.NET 1.6.1
的源碼,哈哈。。。找著根了
一、根位置 MappedStatement.cs
ibaits的數(shù)據(jù)真實操作都交給了這個類。其中用一大堆與select相關操作的方法以及insert update delete相關方法,內(nèi)存泄漏就在這些方法上。簡單看一下ExecuteInsert(insert)方法的代碼:
二、原因 IDispose 接口得顯示調(diào)用
using并不能釋放這些非托管資源
三、解決方法:看上面代碼
四、總結(jié)
以前用ibaits怎么就沒有發(fā)現(xiàn)在呢?
我想這與項目的實際應用場景有關,問題一直都存在,只是沒有顯現(xiàn)吧了。
大多數(shù)據(jù)時候,用戶的輸入?yún)?shù)只有幾個,相對較少,而且調(diào)用頻度應該不高。
而這個應用場景走的卻是另一個極端:
調(diào)用頻度極高:
數(shù)據(jù)中心實時采集4家公司的數(shù)據(jù),且數(shù)據(jù)更新高峰在開收盤前后,中午休市最為集中,每天的數(shù)據(jù)更新在3000K左右,這些數(shù)據(jù)要及時發(fā)布到5個數(shù)據(jù)庫中
參數(shù)超多:
近200張表中有50多張賬務相關的表字段個數(shù)在100到230之間
這些字段最終是要轉(zhuǎn)換成 INSERT 與 UPDATE 語句中的參數(shù),
怪不得程序顯示超多OarcleParamter 對象無法回收,它不多才怪。。。
不過還好,加了上面的代碼后,程序內(nèi)存近期還沒超過150M,多在100M左右
如果你也有用IBAITS.NET,你可要小心了。。
這個問題其實是由 IDispose 接口引起的, 不知道JAVA是什么樣子,源碼還沒仔細看
JAVA版本的3.0出來時間也不短了,易用性比 IBATIS.NET 1.6.1 要強太多了。
不知道 .NET 版本的更新什么時候出。。。
一、根位置 MappedStatement.cs
ibaits的數(shù)據(jù)真實操作都交給了這個類。其中用一大堆與select相關操作的方法以及insert update delete相關方法,內(nèi)存泄漏就在這些方法上。簡單看一下ExecuteInsert(insert)方法的代碼:
// 初始化 command 的參數(shù) _preparedCommand.Create(request, session, this.Statement, parameterObject); // 用 using 處理 command using (IDbCommand command = request.IDbCommand) { try { if (_statement is Insert) { generatedKey = command.ExecuteNonQuery(); } // Retrieve output parameter if the result class is specified else if (_statement is Procedure && (_statement.ResultClass != null) && _sqlMap.TypeHandlerFactory.IsSimpleType(_statement.ResultClass)) { ......// 省 } if (selectKeyStatement != null && selectKeyStatement.isAfter) { IMappedStatement mappedStatement = _sqlMap.GetMappedStatement(selectKeyStatement.Id); generatedKey = mappedStatement.ExecuteQueryForObject(session, parameterObject); ObjectProbe.SetMemberValue(parameterObject, selectKeyStatement.PropertyName, generatedKey, request.DataExchangeFactory.ObjectFactory, request.DataExchangeFactory.AccessorFactory); } //ExecutePostSelect(request); RetrieveOutputParameters(request, session, command, parameterObject); } // 下面這個 finally 段是我加上去的,我不確定 command 的 dispose是否會調(diào)用相關Paramters中對象相應的 dispose 方法,所以就用了下面這個,因為程序中顯示大量IDataParamter 對象無法回收 finally { if (command.Parameters.Count > 0){ MethodInfo mi = command.Parameters[0].GetType().GetMethod("Dispose", BindingFlags.Instance | BindingFlags.Public); if (mi != null) for (int i = 0; i < command.Parameters.Count; i++) mi.Invoke(command.Parameters[i], null); } command.Dispose(); } }
二、原因 IDispose 接口得顯示調(diào)用
using并不能釋放這些非托管資源
三、解決方法:看上面代碼
四、總結(jié)
以前用ibaits怎么就沒有發(fā)現(xiàn)在呢?
我想這與項目的實際應用場景有關,問題一直都存在,只是沒有顯現(xiàn)吧了。
大多數(shù)據(jù)時候,用戶的輸入?yún)?shù)只有幾個,相對較少,而且調(diào)用頻度應該不高。
而這個應用場景走的卻是另一個極端:
調(diào)用頻度極高:
數(shù)據(jù)中心實時采集4家公司的數(shù)據(jù),且數(shù)據(jù)更新高峰在開收盤前后,中午休市最為集中,每天的數(shù)據(jù)更新在3000K左右,這些數(shù)據(jù)要及時發(fā)布到5個數(shù)據(jù)庫中
參數(shù)超多:
近200張表中有50多張賬務相關的表字段個數(shù)在100到230之間
這些字段最終是要轉(zhuǎn)換成 INSERT 與 UPDATE 語句中的參數(shù),

不過還好,加了上面的代碼后,程序內(nèi)存近期還沒超過150M,多在100M左右
如果你也有用IBAITS.NET,你可要小心了。。
這個問題其實是由 IDispose 接口引起的, 不知道JAVA是什么樣子,源碼還沒仔細看
JAVA版本的3.0出來時間也不短了,易用性比 IBATIS.NET 1.6.1 要強太多了。
不知道 .NET 版本的更新什么時候出。。。
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
