2013-12-18 64 views
2

我似乎有一些大內存消耗問題。當我第一次加載包含gridview和observablecollection的wpf應用程序時,該應用程序大約爲10mb。WPF內存問題與圖像

當我點擊GridView中的一個項目它打開其中包含被傳遞一個base64字符串,然後我轉換成一個BitmapImage的

然後,應用程序從10MB跳到高達約123MB的圖像控制的另一個窗口。原始圖像大小爲64k,但我所存儲的所有圖像都是base64字符串,我將其轉換回byte [],然後轉換爲BitmapImage。 是的,我的意思是做到這一點。

當我關閉窗口時,沒有一個ram獲得釋放。我甚至嘗試過調用GC。

我用下面的代碼打開的base64圖像到

var bitmapImage = new BitmapImage(); 
bitmapImage.BeginInit(); 
bitmapImage.CacheOption = BitmapCacheOption.None; 
bitmapImage.StreamSource = new SIO.MemoryStream(imageBytes); 
bitmapImage.EndInit(); 
return bitmapImage; 

那然後被分配到Image.Source

+1

這聽起來像分析的工作。 –

+0

如果將CacheOption更改爲'BimapCacheOption.OnLoad',你會發現有什麼區別嗎?還要檢查你是不是掛在'imageBytes'的副本上。 – Nathan

回答

1

下面是一些提示和猜測,但是如果你使用的內存分析器你會能夠看到什麼是佔用內存。 (例如the CLR profiler also VS 2012 ad 2013 come in-built memory profile tools,和其他商業的:.NET Memory Profiling Tools


  • 爲什麼你指定從hereCacheOptionBitmapCacheOption.None,上面寫着:

不要創建一個內存存儲。圖像的所有請求都直接由圖像文件填充。

相反,你可以使用OnLoad

緩存整個圖像到內存在加載時。圖像數據的所有請求都從內存存儲中填充。

我讀爲:如果您在多個位置顯示圖像,他們共享相同的底層內存。所以,如果你在多個地方展示相同的圖像,肯定會更好。

  • 在示例here的評論中發現的另一個末端:

爲了節省顯著應用存儲器,設置DecodePixelWidth或圖像源的所需 的BitmapImage的值的
DecodePixelHeight渲染圖像的高度和寬度。如果你不這樣做,應用程序將緩存圖像,就好像它被渲染爲其正常尺寸,而不是顯示的尺寸即 。

  • 你爲什麼要使用Base64字符串,爲什麼不使用二進制數據,即byte[] S'每個字符串有多少個副本供您參考?
+0

謝謝分析器指出我正確的方向,現在已經把我的內存使用率從123mb降到了25mb左右,這是合理的。 – Tsukasa

+0

@Tsukasa,我很好奇,是什麼問題? – markmnl

+0

它實際上與我正在做的一個加密類有關,並且忘記了我正在調用它。這是吃ram的原因,因爲它沒有釋放物體。我沒有意識到分析工具。認爲我需要養成從現在開始使用它們的習慣。 – Tsukasa

0

約定的BitMap不會釋放其存儲器(試過並且對存儲器泄漏感到厭倦)。然而 試試這個link

閱讀最後的評論可能是這種解決方法可能解決問題