WPF内存、资源释放问题

时间:2021-03-14 05:02:24
在搜wpf相关资料时看到说wpf程序很耗内存,现在想优化下自己的程序。

搜了下内存、资源释放的资料,什么GC啊、Dispose啊、托管资源啊、非托管资源啊都是这些,但看不懂。

我想问下怎样可以简单优化自己的程序呢??

例如定义了一个string s = "abc";是不是用完后,s = null;这样就会释放s的资源?

window.Close()后,是不是该窗体的资源就释放了?不是的话要怎么释放??

8 个解决方案

#1


你什么都不用写,几秒钟之后就自动被GC释放了。而且这个时间点是经过.net设计师亲自测试优化过的。

#2


我可以告诉你两三天经验,但是我恐怕你一时半刻也只是当作随便一说。

通常需要打印程序进入各种方法的日志,然后看看假设在一整“疯狂”操作之后,操作几乎静止下来后,程序会不会还在无休止地运行着什么,甚至产生了循环。好的情况是从日志可以看到程序处理几乎停下来了。

通常要在自动化测试中写一条语句去判断某些处理(异步回调、事件处理)是否意外地“重新进入”了。这往往说明某些事件注册到更大的、生命周期很长的对象上,从而当程序已经移除了某些组件之后,这些组件其实无法真正被GC回收。这就是所谓的“实践溢出”问题。实际上既然使用 += 来注册事件,那么就应该使用 -= 来注销事件处理。不注销,就会使得成千上万(甚至几十万上百万)的组件无法真正销毁。

#3


两三天  -->  两三条


如果你只是做一般入门书上作为范例的那种编程也就算了。

如果是成熟的产品,那么使用wpf/silverlight这种平台编程其实比winform要复杂多了。因为只有大量异步并发多线程编程才能让程序变得流程,然后这就为调试带来的巨大挑战。没有测试驱动的习惯,没有自己做一套自动化测试系统,靠书上那点理论,你很快就会在调试巨多多线程程序代码面前失去耐心的。

#4


谢谢楼上的,我是要做一个产品,所以希望自己的程序可以做得更好点。

你说什么都不用做?但网上说有人做了一个小程序,过了一段时间后,内存被占用了几百Mb,这样正常?

有什么好的wpf程序优化方面的资料?或者我要去看什么书??或者要做些什么?

麻烦高手指导下,先谢谢大家了!!

#5


学习了。。。
引用 2 楼 sp1234 的回复:
我可以告诉你两三天经验,但是我恐怕你一时半刻也只是当作随便一说。

通常需要打印程序进入各种方法的日志,然后看看假设在一整“疯狂”操作之后,操作几乎静止下来后,程序会不会还在无休止地运行着什么,甚至产生了循环。好的情况是从日志可以看到程序处理几乎停下来了。

通常要在自动化测试中写一条语句去判断某些处理(异步回调、事件处理)是否意外地“重新进入”了。这往往说明某些事件注册到更大的、生命周……

#6


LZ  你用C#写的话 就不用管内存的释放神马的~  因为有CLR 有托管堆~ 

#7


呵呵,看到一个个说了一大堆,都没有解决问题,其实我也经常遇到此类问题。都说。net自动回收。但是靠自动回收有时真的不行。所以代码写的好不好,必须考虑性能,多线程等,我的此类问题也没解决。

#8


引用 2 楼 sp1234 的回复:
我可以告诉你两三天经验,但是我恐怕你一时半刻也只是当作随便一说。

通常需要打印程序进入各种方法的日志,然后看看假设在一整“疯狂”操作之后,操作几乎静止下来后,程序会不会还在无休止地运行着什么,甚至产生了循环。好的情况是从日志可以看到程序处理几乎停下来了。

通常要在自动化测试中写一条语句去判断某些处理(异步回调、事件处理)是否意外地“重新进入”了。这往往说明某些……


我程序也是内存一下几白M了。看了你这个以后实验了一下。还真是你说的原因。+=的事件会无效循环。我不是注销。而是只在程序一个地方生成事件。这样资源释放了。

你给了我很大启发。为了后来人看懂。我贴点代码吧

我的f里面自定义了一个事件。然后再其他地方生成的时候控件的事件+=。但是我的TreeView一刷新。我吧TreeView的ITEM CLEAR掉。然后重新加TreeViewItem对象(通过GetreeView方法)。这样当TreeView刷新几次以后。内存就上到几白M了。我看了楼上那个提示以后才发现是因为程序在GetreeView里面 += 注册事件 这个里面 无限循环出来事件。
  private TreeViewItem GetreeView(obj f)
        {  f.UserStatuChange+= 注册事件
}
最后解决方法:
 程序启动的时候 f.UserStatuChange+= 注册事件。 然后再GetreeView这个方法里面去掉 上面这代代码。
这样程序只有在一个地方注册了 f.UserStatuChange+=事件。 事件不会无限循环。

#1


你什么都不用写,几秒钟之后就自动被GC释放了。而且这个时间点是经过.net设计师亲自测试优化过的。

#2


我可以告诉你两三天经验,但是我恐怕你一时半刻也只是当作随便一说。

通常需要打印程序进入各种方法的日志,然后看看假设在一整“疯狂”操作之后,操作几乎静止下来后,程序会不会还在无休止地运行着什么,甚至产生了循环。好的情况是从日志可以看到程序处理几乎停下来了。

通常要在自动化测试中写一条语句去判断某些处理(异步回调、事件处理)是否意外地“重新进入”了。这往往说明某些事件注册到更大的、生命周期很长的对象上,从而当程序已经移除了某些组件之后,这些组件其实无法真正被GC回收。这就是所谓的“实践溢出”问题。实际上既然使用 += 来注册事件,那么就应该使用 -= 来注销事件处理。不注销,就会使得成千上万(甚至几十万上百万)的组件无法真正销毁。

#3


两三天  -->  两三条


如果你只是做一般入门书上作为范例的那种编程也就算了。

如果是成熟的产品,那么使用wpf/silverlight这种平台编程其实比winform要复杂多了。因为只有大量异步并发多线程编程才能让程序变得流程,然后这就为调试带来的巨大挑战。没有测试驱动的习惯,没有自己做一套自动化测试系统,靠书上那点理论,你很快就会在调试巨多多线程程序代码面前失去耐心的。

#4


谢谢楼上的,我是要做一个产品,所以希望自己的程序可以做得更好点。

你说什么都不用做?但网上说有人做了一个小程序,过了一段时间后,内存被占用了几百Mb,这样正常?

有什么好的wpf程序优化方面的资料?或者我要去看什么书??或者要做些什么?

麻烦高手指导下,先谢谢大家了!!

#5


学习了。。。
引用 2 楼 sp1234 的回复:
我可以告诉你两三天经验,但是我恐怕你一时半刻也只是当作随便一说。

通常需要打印程序进入各种方法的日志,然后看看假设在一整“疯狂”操作之后,操作几乎静止下来后,程序会不会还在无休止地运行着什么,甚至产生了循环。好的情况是从日志可以看到程序处理几乎停下来了。

通常要在自动化测试中写一条语句去判断某些处理(异步回调、事件处理)是否意外地“重新进入”了。这往往说明某些事件注册到更大的、生命周……

#6


LZ  你用C#写的话 就不用管内存的释放神马的~  因为有CLR 有托管堆~ 

#7


呵呵,看到一个个说了一大堆,都没有解决问题,其实我也经常遇到此类问题。都说。net自动回收。但是靠自动回收有时真的不行。所以代码写的好不好,必须考虑性能,多线程等,我的此类问题也没解决。

#8


引用 2 楼 sp1234 的回复:
我可以告诉你两三天经验,但是我恐怕你一时半刻也只是当作随便一说。

通常需要打印程序进入各种方法的日志,然后看看假设在一整“疯狂”操作之后,操作几乎静止下来后,程序会不会还在无休止地运行着什么,甚至产生了循环。好的情况是从日志可以看到程序处理几乎停下来了。

通常要在自动化测试中写一条语句去判断某些处理(异步回调、事件处理)是否意外地“重新进入”了。这往往说明某些……


我程序也是内存一下几白M了。看了你这个以后实验了一下。还真是你说的原因。+=的事件会无效循环。我不是注销。而是只在程序一个地方生成事件。这样资源释放了。

你给了我很大启发。为了后来人看懂。我贴点代码吧

我的f里面自定义了一个事件。然后再其他地方生成的时候控件的事件+=。但是我的TreeView一刷新。我吧TreeView的ITEM CLEAR掉。然后重新加TreeViewItem对象(通过GetreeView方法)。这样当TreeView刷新几次以后。内存就上到几白M了。我看了楼上那个提示以后才发现是因为程序在GetreeView里面 += 注册事件 这个里面 无限循环出来事件。
  private TreeViewItem GetreeView(obj f)
        {  f.UserStatuChange+= 注册事件
}
最后解决方法:
 程序启动的时候 f.UserStatuChange+= 注册事件。 然后再GetreeView这个方法里面去掉 上面这代代码。
这样程序只有在一个地方注册了 f.UserStatuChange+=事件。 事件不会无限循环。