内存泄漏在 WPF 和 Silverlight 提防

瑞奇韭菜礼物 ︰

内存泄漏在 WPF 和 Silverlight 提防

内存泄漏在 WPF 和 Silverlight 提防

WPF 和 Silverlight 允许您定义您的用户界面,用最少的代码将其绑定到数据源,意思说,你可能会没有意识的造成内存泄漏。因为 Silverlight 和 WPF 应用程序并为全状态,使我们能够保持状态的复杂的数据结构,以及丰富的 UI 元素的形式,这可以将添加到大小的内存泄漏,当事情出差错。

陷阱 1

未注册的事件

经典的泄漏常见到所有的.NET 应用程序和开发商共同监督。如果您创建一个事件处理程序来处理事件发生一些其他对象中,然后,如果你不清除链接,当你已经完成,不需要强将留下参考。

说我订阅OnPlaced事件我订单类,说这段代码执行按钮点击 ︰

Order newOrder=new Order
(“EURUSD”, DealType.Buy, Price ,PriceTolerance, TakeProfit, StopLoss);

newOrder.OnPlaced+=OrderPlaced;
m_PendingDeals.Add(newOrder);

当价格是正确的时订单完成,并调用该OnPlaced事件,由OrderPlaced方法 ︰

void OrderPlace(Order placedOrder)
{
	m_PendingDeals.Remove(placedOrder);
}

在我们订阅OnPlaced事件,并引用将使 Order 对象活着尽管我们已经从集合中删除它时, OrderPlaced事件处理程序仍然适用对从订单对象的引用。它是很容易犯这个错误。

陷阱 2

数据绑定

你没看错;数据绑定,您所依赖的东西可以导致内存泄漏。严格地说它是实际上的方式使用它导致泄漏。如果你有一个数据绑定到其父属性的子对象,可以会发生内存泄漏。下面显示了一个这样的例子。

<Grid Name="mainGrid">

    <TextBlock Name=”txtMainText”
    Text="{Binding ElementName=mainGrid, Path=Children.Count}" />

</Grid>

正如Children.Count如果绑定的属性是一个PropertyDescriptor属性,将只会发生的情况。这是因为,为了检测PropertyDescriptor属性发生更改时,框架必须订阅ValueChanged事件,反过来设置一个强引用链。

陷阱 3

静态事件

上一个静态对象的事件订阅将设置对处理该事件的任何对象的强引用。静力学,一个引用,应用程序域执行期间保持和因此这么做他们的所有引用。防止垃圾回收的强引用,只是内存泄漏的另一个名字。

陷阱 4

命令绑定

命令绑定允许您单独常见应用程序命令 (和它们的调用) 从处理它们的。您可以编写您的类来处理特定的命令,或不,和甚至表示是否可以执行这些命令。当这些绑定离开有害的强引用,身边躺着的时候出现问题,多和其他人一样,我们已经看到。

说我设置了一些子窗口中的代码来处理削减在父窗口内执行时。我第一次创建CommandBinding,,然后简单地将其添加到父窗口CommandBindings集合 ︰

好消息是.NET 框架现在照顾你,释放对象,也是超持谨慎态度。它锻炼是否认为一个特定的对象是要需要你的程序运行,而它只会释放该对象,如果它能完全保证,该对象不会再需要。

CommandBinding cutCmdBinding = new CommandBinding
(ApplicationCommands.Cut, OnMyCutHandler, OnCanICut);

 mainWindow.main.CommandBindings.Add(cutCmdBinding);

...
void OnMyCutHandler (object target, ExecutedRoutedEventArgs e)
{

    MessageBox.Show("You attempted to CUT");
}

void OnCanICut (object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

此代码泄漏因为我们就要出发的强引用指向孩子的mainWindow.main.CommandBindings对象中。结果,甚至当孩子关闭时,它将仍然在内存中。

陷阱 5

Dispatchertimer 泄漏

DispatcherTimer使用不当会导致内存泄漏。下面的代码创建新的DispatcherTimer在用户控件中,并为了便于看到石油泄漏,同时我还叫我的心头,使泄漏更加明显的字节数组。

public byte[] myMemory = new byte[50 * 1024 * 1024];

System.Windows.Threading.DispatcherTimer _timer = new System.Windows
.Threading.DispatcherTimer();
int count = 0;

private void MyLabel_Loaded(object sender, RoutedEventArgs e)
{

	_timer.Interval = TimeSpan.FromMilliseconds(1000);

	_timer.Tick += new EventHandler(delegate(object s, EventArgs ev)

	{
		count++;
		textBox1.Text = count.ToString();
		});

	_timer.Start();
}

在我的主窗口上我就StackPanel (后首先删除儿童) 按钮点击将泄漏内存的每次点击添加用户控件的实例。它向后使用蚂蚁内存探查器跟踪表明UserControl作为泄漏源。

问题是,再一次举行,这次由调度员,持有的活DispatcherTimers集合的引用。从集合的强引用保持每个用户控件还活着,并因此泄漏内存。

转载于:https://www.cnblogs.com/naliang/p/5438433.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值