[問題] Task StartNew過多,導致記憶體爆量
===前情提要===
目前在重整資料庫的資料(約2,800萬筆),所以必須一筆一筆爬
資料爬出來後會做兩種處理,再建立新的資料庫
資料庫使用mongodb,先把整個collection做findall,再丟入foreach的迴圈去跑
用了兩個foreach,為省略版面,以下code只寫一個foreach作為範本
===方案A,單執行緒===
var result = coll.FindAll();
foreach(var doc in result)
{
工作!();
}
結果:
工作A處理效能:20筆/秒
工作B處理效能:10筆/秒
慢慢做記憶體跟CPU都不炸
===方案B,多執行緒===
var result = coll.FindAll();
foreach(var doc in result)
{
Task Task_CheckData = Task.Factory.StartNew(() =>
{
工作!();
});
}
結果:
工作A處理效能:900up筆/秒,持續加速
工作B處理效能:15up筆/秒,緩慢加速,資料庫效能都被工作A吃掉了
爐~心~超~載~啦~
由於一直生出新的Task,但程式又沒有適當的釋放資源,導致記憶體持續上升
吃完所有實體記憶體後執行速度很緩慢,而且也沒有釋放記憶體的情況
===方案C,多執行緒+Dispose===
var result = coll.FindAll();
foreach(var doc in result)
{
Task Task_CheckData = Task.Factory.StartNew(() =>
{
工作!();
});
Task_CheckData.Wait();
Task_CheckData.Dispose();
}
結果:
工作A處理效能:20筆/秒
工作B處理效能:10筆/秒
體悟心靈祥和ˊㄇˋ
已經變成單執行緒的形狀了
===方案D,多執行緒+ContinueWith,失敗===
var result = coll.FindAll();
foreach(var doc in result)
{
Task Task_CheckData = Task.Factory.StartNew(() =>
{
工作!();
});
Task_CheckData.ContinueWith(antecendent =>
{
Task_CheckData_Each.Dispose();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
結果:
程式整個卡住不跑...
D方案比C方案早生出來
因為失敗了所以先前沒key
===問題結論===
大概出在Task的使用上
但餵狗後還是沒發現比較好的解決方案
或許是我關鍵字下錯QQ
請版上先知指教,謝謝
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.82.219.136
※ 文章網址: https://www.ptt.cc/bbs/C_Sharp/M.1468566664.A.390.html
→
07/15 15:13, , 1F
07/15 15:13, 1F
→
07/15 15:14, , 2F
07/15 15:14, 2F
→
07/15 15:16, , 3F
07/15 15:16, 3F
→
07/15 15:16, , 4F
07/15 15:16, 4F
→
07/15 15:17, , 5F
07/15 15:17, 5F
→
07/15 15:18, , 6F
07/15 15:18, 6F
補充方案D,感謝各位
→
07/15 15:34, , 7F
07/15 15:34, 7F
→
07/15 15:35, , 8F
07/15 15:35, 8F
→
07/15 15:37, , 9F
07/15 15:37, 9F
→
07/15 15:37, , 10F
07/15 15:37, 10F
→
07/15 15:38, , 11F
07/15 15:38, 11F
→
07/15 15:38, , 12F
07/15 15:38, 12F
→
07/15 15:38, , 13F
07/15 15:38, 13F
→
07/15 15:41, , 14F
07/15 15:41, 14F
將迴圈改為Parallel.ForEach
工作A處理效能:500up筆/秒,緩慢增加
工作B處理效能:230up筆/秒,緩慢增加
記憶體有增長,但是成長的量不大,且有明顯回收記憶體的現象,持續觀察~
非常感謝!
推
07/15 15:53, , 15F
07/15 15:53, 15F
→
07/15 15:53, , 16F
07/15 15:53, 16F
的確是..之後會試著把Task在迴圈外宣告
然後迴圈內加入新工作
感恩!
→
07/15 15:54, , 17F
07/15 15:54, 17F
→
07/15 15:55, , 18F
07/15 15:55, 18F
→
07/15 15:56, , 19F
07/15 15:56, 19F
→
07/15 15:57, , 20F
07/15 15:57, 20F
→
07/15 15:59, , 21F
07/15 15:59, 21F
切chunk的方式我有想過,但是資料庫資料蠻不連續的
可能需要用第A筆至第B筆來切
速度的部分,目前是連線去呼叫資料庫,查詢時間略久,每做一次查詢回傳約1xx毫秒
一個工作內會做1~4次查詢
感謝你的建議與問題~~
※ 編輯: moumou17 (111.82.219.136), 07/15/2016 16:06:00
→
07/15 16:35, , 22F
07/15 16:35, 22F
→
07/15 16:36, , 23F
07/15 16:36, 23F
→
07/15 16:36, , 24F
07/15 16:36, 24F
→
07/15 16:40, , 25F
07/15 16:40, 25F
→
07/15 16:40, , 26F
07/15 16:40, 26F
→
07/15 17:12, , 27F
07/15 17:12, 27F
→
07/15 17:13, , 28F
07/15 17:13, 28F
推
07/16 09:46, , 29F
07/16 09:46, 29F