.NET CORE 2.0 zkweb.system.drawing Linux下記憶體BUG
阿新 • • 發佈:2019-02-02
1.zkweb.system.drawing linux下卡死
請先看這樣一段程式碼:
var image = new Bitmap(int_ImageWidth, letterHeight); ... image = TwistImage(image, true, Next(1, 3), Next(4, 6)); MemoryStream ms = new MemoryStream(); image.Save(ms, ImageFormat.Jpeg); image.Dispose(); //正弦扭曲 public Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase) { var PI = 6.283185307; var destBmp = new Bitmap(srcBmp.Width, srcBmp.Height); var graph = Graphics.FromImage(destBmp); graph.FillRectangle(new SolidBrush(Color.White), 0, 0, destBmp.Width, destBmp.Height); graph.Dispose(); double dBaseAxisLen = bXDir ? destBmp.Height : destBmp.Width; for (var i = 0; i < destBmp.Width; i++) { for (var j = 0; j < destBmp.Height; j++) { double dx = 0; dx = bXDir ? PI * j / dBaseAxisLen : PI * i / dBaseAxisLen; dx += dPhase; var dy = Math.Sin(dx); int nOldX = 0, nOldY = 0; nOldX = bXDir ? i + (int)(dy * dMultValue) : i; nOldY = bXDir ? j : j + (int)(dy * dMultValue); var color = srcBmp.GetPixel(i, j); if (nOldX >= 0 && nOldX < destBmp.Width && nOldY >= 0 && nOldY < destBmp.Height) { destBmp.SetPixel(nOldX, nOldY, color); } } } srcBmp.Dispose(); return destBmp; }
在windows上跑這樣一段程式碼時沒有任何問題,當我釋出在linux上的時候,居然死掉了,是死掉,沒有任何異常,網頁一直在等待中,搞得我非常納悶,對於我這個有強迫症的人來說,直接無限測試,找到位置,多次測試尋找中偶然得到一份記憶體錯誤的資訊
這個BUG是出在image.save 是時候,應該是記憶體錯誤,導致不再向下執行,不止這個執行緒,整個dotnet 癱瘓,無法接收處理新的請求,但卻沒有多餘的CPU佔用。導致這個問題出現的是TwistImage 中的srcBmp.Dispose(); 把這個放在最後一起釋放可以暫時迴避掉這個BUG
這個問題應該是因為這個外掛使用了非託管記憶體,導致底層出現記憶體溢位或者訪問已經釋放掉的指標。至於為何windows沒有崩潰,很有可能是因為程式碼是根據環境進行呼叫的,包括呼叫的系統api都可能不同,所以僅導致了僅linux下出現記憶體問題