C# 实现Windows phone silverlight页面的Dispose和Finalize
我有一个图形、弹出窗口和动画的大解决方案。我发现在页面导航过程中出现了大量内存泄漏 尝试 因此,我尝试了第一种解决方案:C# 实现Windows phone silverlight页面的Dispose和Finalize,c#,mvvm,memory-leaks,windows-phone,dispose,C#,Mvvm,Memory Leaks,Windows Phone,Dispose,我有一个图形、弹出窗口和动画的大解决方案。我发现在页面导航过程中出现了大量内存泄漏 尝试 因此,我尝试了第一种解决方案: protected override void OnNavigatedTo(NavigationEventArgs e) { if (App.RootFrame.CanGoBack) App.RootFrame.RemoveBackEntry(); GC.Collect(); base.OnNav
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (App.RootFrame.CanGoBack)
App.RootFrame.RemoveBackEntry();
GC.Collect();
base.OnNavigatedTo(e);
}
这来自MSDN和Stackoverflow上的多个源,应该会删除为页面存储的内存。事实并非如此,我不确定代码的MVVM结构是否以某种方式保存了信息。然后,我尝试实现解构器,并在触发事件时强制值为null,如下所示:
~SecondScreen()
{
In_Game_Crest = null;
currentViewModel = null;
}
这是我为所有页面、弹出窗口和用户控件所做的。然后,我再次使用debug检查了代码,解构器中没有一个页面被激活。这让我尝试使用MVVMLight提供的IDisposable
和viewmodelLocator
,但没有成功
调查
我已经阅读了以下关于这个问题的内容:
问题
但它让我困惑,而不是帮助我。我应该如何为我的windows phone页面实现dispose和finalize方法
由于我使用的是MVVM结构,这些方法应该在ViewModel中实现,还是在给定页面后面实现,或者两者都实现
如能提供windows Phone的示例,将不胜感激
初次试用Dispose 我读了更多关于这个主题的书,发现最后定稿也许不应该写?但我仍然不确定。但基于此和上面的第一个MSDN链接,我尝试了以下方法:
private bool disposed = false;
public void Dispose()
{
Dispose(true);
// Take yourself off the Finalization queue
// to prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
currentView = null;
popup = null;
Image1 = null;
Image2 = null;
}
// Release unmanaged resources. If disposing is false,
// only the following code is executed.
this.Content = null;
// Note that this is not thread safe.
// Another thread could start disposing the object
// after the managed resources are disposed,
// but before the disposed flag is set to true.
// If thread safety is necessary, it must be
// implemented by the client.
}
disposed = true;
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~FirstPage()
{
Dispose(false);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.Dispose();
base.OnNavigatedFrom(e);
}
但是,当我进入第二个屏幕时,这让我的内存增加了23MB。这又让我想到了一个问题,我应该如何实现,实现什么,以及为什么内存会增加
this=null,base.Dispose()
我见过不同的实现,或者在dispose函数中使用this=null
,或者使用base.dispose()
。我认为,只有当类是IDisposable
时,才可以使用后者?这是路吗?如果是这样,我该怎么做
使用Microsoft Profiler
因此,我使用探查器来验证第一页是否未被删除
从上图可以看出第一页已经存在。在评论中,我被告知要查找实例和对元素的引用。因此,我选择了firstpage的实例并得到:
这里确认第一页从未被销毁。但我被困在这里,我应该如何解释数据?
希望得到一些帮助。当用户离开某个页面时,实际上没有必要进行处理,重新创建对象所带来的性能
影响远远大于在应用程序处于活动状态时将页面放入内存所带来的内存负载。
您应该在从内存中删除对象与重新创建同一组对象之间做出决定。
说到这里,您应该小心使用导航模型。 如果您在用户每次导航到某个页面时都创建对象,但在用户离开时没有实际处理对象,则可能会出现内存问题。
为此,我建议您充分了解应用程序中的
PageBase
和NavigationHelper
或NavigationService
类。
您已经提到,在应用程序的生命周期内,FirstPage
不会从内存中删除,我认为这是理想的。将调试点放在代码中可能创建重对象的地方; 浏览几次不同的页面,然后返回
检查一下你的行为,你可能会对自己有一个清晰的了解
对于所有对象,请检查是否手动调用
Dispose
Dispose
与GarbageCollector
是一个完全不同的概念,Dispose
只是一个契约,开发者应该通过调用它来释放他们认为不再需要在内存中维护的资源,因为平台的垃圾收集是在不确定的时间进行的。
在您发布的示例中,我看到您正在将对象设置为
null
,而没有实际处理。设置为null
只会更改变量所指向的内存位置。
它不会立即销毁该对象。理想的配置应如下所示
//Call on OnClosing or OnExit or similar context
protected override void Dispose(bool isDisposing)
{
if(isDisposing && !_isDisposed){
if(disposeableImage != null){
disposeableImage.Dispose();
disposeableImage = null;
}
}
}
因此,我解决页面内存泄漏的方法是使用以下问题的答案:
仍然存在一些漏洞,这有助于删除情节提要和事件处理程序,以及添加和删除它们。但是一些内存仍然存在,但没有发生泄漏。看在上帝的份上:请不要在生产代码中使用
GC.Collect
,除非有令人信服的理由。对于内存问题,使用内存探查器,找出您认为不应该存在的对象存在的原因。@srramsakthivel我知道这不是首选的解决方案,而是使用c语言,这应该自动完成。但由于我有问题,我尝试了解决办法。请解释什么是内存分析器,并让我参考一个。我只使用实时更新的内存,这样我就可以对应用程序进行实时测试,并查看内存使用情况以获得评测帮助。VisualStudio附带分析器,请对此进行一些研究。很难解决记忆问题。您确实需要使用探查器。@JTIM您必须记住,如果有某个根对象保留对您的对象的强引用,则使用Dispose
或编写终结器对您没有帮助。我们要做的不是实现这些。你应该做的是下载一个内存分析器,并尝试找到使你的对象保持活动状态的根。谢谢你的回复。第一个页面只是一个带有一些动画的登录页面。因此,所有的图形和页面应在导航离开后删除。我很抱歉没有说清楚。关于dispose,许多元素中没有dispose函数。因此,我的问题是: