Sin*_*atr 0 c# wpf memory-leaks
我无法理解这里泄漏的是什么
using GDI = System.Drawing;
public partial class MainWindow : Window
{
[DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr obj);
public MainWindow()
{
InitializeComponent();
var timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(50) };
timer.Tick += (s, a) =>
{
using (var bitmap = new GDI.Bitmap(1000, 1000))
{
var hbitmap = bitmap.GetHbitmap();
var image = Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
image.Freeze();
DeleteObject(hbitmap);
}
};
timer.Start();
}
Run Code Online (Sandbox Code Playgroud)
bitmap?弃置.hbitmap?删除.image?冷冻,但事实并非如此IDisposable.
事实是,这个应用程序会崩溃(在运行约20秒后在我的电脑上)
System.Drawing.dll中发生了未处理的"System.OutOfMemoryException"类型异常
附加信息:内存不足.
有任何想法吗?
据我所知,没有泄漏.问题是你要快速分配大型C#对象而垃圾收集器为时已晚了?
以下是一些相关主题:
在C#中进行大型,快速和频繁的内存分配时避免OutOfMemoryException
这是有用的线程:
如果您踢GC.Collect(代数为0..3),您的内存消耗将被修复:
while (true)
{
Thread.Sleep(5);
using (var bitmap = new GDI.Bitmap(1000, 1000))
{
var hbitmap = bitmap.GetHbitmap();
var image = Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
image.Freeze();
DeleteObject(hbitmap);
}
Console.WriteLine("Current memory consumption" + GC.GetTotalMemory(false));
GC.Collect(3);
}
Run Code Online (Sandbox Code Playgroud)
并输出:
Current memory consumption156572
Current memory consumption156572
Current memory consumption156572
Current memory consumption156572
Run Code Online (Sandbox Code Playgroud)
真正的问题是GC不知道你的非托管分配,即使你释放它们.您需要添加内存压力并让GC了解它:
var width = 1000;
var height = 1000;
using (var bitmap = new GDI.Bitmap(width, height))
{
var hbitmap = bitmap.GetHbitmap();
var allocatedSize = width*height*4; // each pixel takes ~4 bytes?!
GC.AddMemoryPressure(allocatedSize);
var image = Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
image.Freeze();
DeleteObject(hbitmap);
GC.RemoveMemoryPressure(allocatedSize);
}
Run Code Online (Sandbox Code Playgroud)
让GC了解底层非托管内存有助于确保GC在正确的位置启动.
| 归档时间: |
|
| 查看次数: |
698 次 |
| 最近记录: |