2014-03-24 110 views
0

所以,我有一個用C#編寫的應用程序(vs2010),使用tesseract 3.02 dll和Charles Weld的terreract.net包裝器執行OCR。C#可能的內存泄漏?

我想我有一個內存泄漏,它似乎是在Pix對象分配的代碼區域。我正在使用PDF,將其轉換爲灰度PNG,然後將其加載到OCR的Pix對象中。當它工作時,它工作得很好。圖像的尺寸很大(每個暗淡的像素爲5100左右),但尺寸不是很大(只有500k左右)。

我的代碼:

在應用程序啓動

初始化引擎:

private TesseractEngine engine = new TesseractEngine(@"./tessdata/", "eng+fra", EngineMode.Default); 

方法將PDF轉換爲PNG,然後調用:

​​

,然後調用以下:

// Perform OCR on the image referenced in the Pix object. 
private String PerformImageOCR(Pix pixImage) 
{ 
    int safety = 0; 

    do 
    { 
     try 
     { 
      // Deskew the image. 
      pixImage = pixImage.Deskew(); 
      //pixImage.Save(@"c:\temp\img_deskewed.png", ImageFormat.Png); // Debugging - verify image deskewed properly to allow good OCR. 

      string text = ""; 

      // Use the tesseract OCR engine to process the image 
      using (var page = engine.Process(pixImage)) 
      { 
       // and then extract the text. 
       text = page.GetText(); 
      } 

      return text; 
     } 
     catch (Exception e) 
     { 
      MessageBox.Show(string.Format("There was an error performing OCR on image, Retrying.\n\nError:\n{0}", e.Message), "Error", MessageBoxButtons.OK); 
     } 
    } while (++safety < 3); 

    return string.Empty; 
} 

我哈哈我們觀察到創建Pix對象時內存使用量跳過了大約31MB,然後在執行OCR時再次跳轉,然後最終比啓動之前穩定了大約33MB。即:如果應用程序在加載後消耗50MB,則加載Pix對象會導致內存使用量跳至約81MB。執行OCR將會看到它達到114 + MB,然後,一旦過程完成並保存結果,內存使用率將穩定在84MB左右。在文件夾中的許多文件中重複此操作最終會導致應用程序以1.5GB左右的速度消耗掉。

我認爲我的代碼沒問題,但是有些東西是堅持資源的。

tesseract和leptonica dlls是用C編寫的,我已經用VS2010重新編譯了它們以及最新或推薦的圖像庫版本。我不確定的是,如何使用Visual Studio從C#應用程序診斷C DLL中的內存泄漏。如果我使用的是Linux,我會使用valgrind之類的工具來幫助我發現泄漏,但是我在窗口方面的泄漏嗅探技巧令人遺憾缺乏。尋找關於如何進行的建議。

+1

我對這個庫不太熟悉,但'Pix'實現了'IDisposable',如果是的話,你在'pixImage'對象上調用Dispose()嗎?這是我看到的唯一的東西。當然,泄漏可能在圖書館裏。您可能需要聯繫開發人員。另外[.NET內存分析器](http:// stackoverflow。com/questions/3927/what-are-some-good-net-profilers)在幫助識別託管代碼中的泄漏方面非常出色(雖然不太擅長未受管理的泄漏)。 – TypeIA

+0

那麼,哪一位分配非託管資源,是處置還是終止? – Jodrell

+0

感謝@dnvrrs,upvoted你的評論是有幫助的! – Jon

回答

0

在這裏讀你的代碼我沒有看到你在任何地方處理你的pix pixImage?在處理x圖像時,這就是佔用所有資源的原因。 在返回字符串結果之前,您應該在pixImage上調用dispose方法。這應該會減少程序使用的資源數量。

+0

Pix確實實現了idisposable。當我完成時,我嘗試了調用Dispose的建議,但是這不會改變內存使用情況。 – Jon

+0

然後我敢說API的實現是錯誤的。據我估計,Pix圖像保存非託管資源。我會在論壇上發佈你的問題(如果他們有),或者直接郵寄給他們尋求支持。 – woutervs

+0

阿哈...知道了! Deskew()方法增加了dll中pix對象的refcount。調用Dispose()會在每次調用時將refcount減1,並且只在refcount = 0時釋放資源。所以,感謝你和@dvnrrs(不知道誰先回答同樣的建議),指出我需要看的方向。問題雖然..我雖然不應該自己調用Dispose方法?我已經閱讀了很多關於這方面的論點,而且我還不清楚應該或不應該。顯然,在這種情況下,我必須,但是......什麼是「經驗法則」? – Jon

0

我不熟悉Tesseract或包裝,但對於內存分析問題,如果您有Visual Studio 2012/2013,則可以使用性能嚮導。我知道它在Ultimate中可用,但在其他版本中無法確定。

http://blogs.msdn.com/b/dotnet/archive/2013/04/04/net-memory-allocation-profiling-with-visual-studio-2012.aspx

這兩種東西在你的代碼或東西包裝不恰當地處置非託管對象。我的猜測是它在包裝中。運行性能嚮導或其他C#內存分析器(如JetBrains DotTrace可能幫助您追蹤它。