C# WinForm 运行久了就内存不足

转载地址:https://www.debugease.com/csharp/4441632.html

1、WinForm,主窗体-子窗体模式
2、关闭子窗体,使用Hide(),打开子窗体,使用Show()
3、软件就是ERP、进销存,支持图片,Socket上传下载
4、表格数据多大概这些,然后,软件运行久了,就达到几百M,然后用着用着就突然弹出内存不足,好恐怖,请问解决思想好,谢谢。

===============================================================================
解决方案 »

32位程序,最大内存 3.2 G 左右。
窗体 尽量不要 Hide() 、Visible —— 能关就关,最好能调用 窗体的 Dispose() 函数(释放组件、释放数据都彻底一些)
打开任务管理器:工具栏>选择列> 勾选 “用户对象”、“GDI对象”、“句柄数”—— 这三列 都不允许超过 10000 (超过程序直接崩溃)

主要是我用Hide(),那再次打开窗口的话,直接就Show出来,不会New一个新对象。这样挺好。

仅从你的描述,看不出问题。你的所谓 hide()、show() 并不是别人口中所说的“关闭窗体、打开窗体”,而纯粹是隐藏、显示的意思,所以这不会出现什么问题。真正的内存溢出是需要测试的。但是看起来、感觉到你的开发技术本身就达不到测试驱动开发的程度,这就很难说深入技术的内容。总之招聘专业开发人员进行开发和测试,测试几万遍之后才敢上线,这是产品思路。

不管别人如何给你说什么看代码,注意回收资源等等。。你都不要相信。。因为Winform确实不适合做大一点的商业软件开发。。不然呢我也认为Winform确实是很方便做桌面的。。为什么那些大些商业软件不选择Winform呢?如photoshop, CorelDraw, UG,PRO/E,AutoCad真的方便功能强大这些软件早就用Winform改写了,你说是不是呢?
你就把WinForm当一个玩具和学习编程的入门工具吧。。就如微软当年的VB,也许当年的VB都要比Winform好很多

某一个窗口、自定义控件有没有内存泄漏问题,这个是要通过写程序来测试的。测试出bug之后才可能调试,不可能靠用鼠标随便“点点点”就能开始调试出来bug,所以专业的开发要以测试驱动开发,而不是随便拼凑界面。那么这就在开发技术上存在着你完全没有学过的技术过程,当你提不出问题时也就不会免费给你回答,所以这就不太方便讨论了。

正常的Winform写的服务跑半个月都没问题,.net的GC 是很高效的。
肯定是你有些资源占用没释放,using{} 了解一下

上WPF

使用资源的方式不能太粗放
1。凡涉及非托管资源,使用完后一定要有释放操作
2。重点关注循环调用的代码
3。关注异常处理环节: 很多情况下,泄漏是由于异常处理跳过了回收处理逻辑
4。借助第三方工具,比如Process Explorer,确定句柄是否有泄漏

hide()只是隐藏,关闭是close

在内存占用最高的时候,拉一个进程dump,
简单的用任务管理器就可以,然后用windbg分析一下主要的内存占用是什么内容

纯粹的 hide和show,应该不会造成内存泄漏。
主要考虑有什么资源没有释放,这个问题就大的去了。

因为光从你的描述,是很难找到winform本身的毛病的。
其实还是代码上的问题。

多检查检查代码中 new 的对象最终有么有释放掉,只有新建没有释放内存必然溢出。

是否有 event handler 忘了remove?推荐使用 Ants Memory Profiler 内存检测工具。

Winform主要是 new 对象要用完就释放掉,不然一直占有内存,还有hide少用,这是个隐藏窗口,程序在运行窗口看不见。但窗口在运行,还是占用内存的

vs的菜单 分析->性能探查器 打开性能探查器窗口,选中"内存使用率",点击开始.你的程序会启动,并且vs会在后台收集程序使用内存的状态你可以将你程序的各个功能都反复用一下,模拟正常使用的情况当你的程序结束后,vs会根据程序运行期间收集的数据生成一份报告,报告中会详细列出每个模块,每个对象等使用的内存根据报告应该可以比较清楚的发现内存使用超出正常值的位置,然后针对性的查找原因.另外,既然内存使用超出预期,那么一般也就是那么几种可能,
是否使用了非托管资源?如果使用了,那么重点检查一下是否正确销毁了.
是否重复创建了托管对象,无用后却仍然保持了对其的引用,导致垃圾回收器无法自动将其销毁还是在vs的分析菜单中,还有一项"运行代码分析->针对解决方案分析",此功能可以分析出很多平常未注意的问题,这些问题会以警告或通知的方式显示到错误窗口中.仔细看看其中是否有对对象销毁的建议还有一些插件,比如著名的resharper也可以找出很多隐性问题

1,数据表数据就是占用内存的原因,肯定是没有做好优化,比如数据达到100条就使用翻页等等;
2,数据上传和下载,这里使用socket,在传输的时候肯定要写入流,那么流是否及时释放等等;
3,检查程序是否有whie无限遍历任务,如果要那么要加上线程阻塞100mm秒;
4,是否使用了多线程;
5,重要:在做哪些操作时导致程序崩溃;

比如说一个组件占用(从1K开始)100M内存,另一个占用(也是从1K开始)10K内存,你怎么能说前一个就有内存泄漏?所以单独靠这类意见是说明不了开发方法的。检测内存泄漏,就是要写代码来判断一个组件再普通地、使用完毕之后,(比如说)10秒钟之后到底有没有被 GC 自动处理掉。别的一般来说都是一些靠乱猜了。当然平常要知道一些良好设计开发的模式,但是这些模式更多地是整体素质问题。并不是具体测试代码。

你问问一个有经验的开发人员,如过他告诉你就是用一个“dump工具”来随便猜,或者他就是告诉你静态查看代码来乱猜,那你就没有找对人。真正要找到内存泄漏是你自己写测试代码。以测试为准,不是靠各种理论标题党来作为论据去猜的。

首先,推荐你安装VS2017以上版本,虽然我记得我说的功能2015也有,但是我记不太清什么版本的才有了。然后你可以打开“诊断工具”接下来内存占用变化一目了然:并且你可以通过“截取快照”来对比内存变化前后的项目变化用这种方法可以分析各种内存溢出的具体原因,当然如果你是用VS2010的老古董,我也不知道怎么拯救你,你可以至少找一台电脑安装个2017分析一下,确认位置再回去2010改代码都行。

偷懒的方法:
你可以主动调用GC.Collect()强制GC,比如设置一个定时器周期性调用GC.GetTotalMemory,如果超过某个安全值(你自己设定),就调用GC.Collect…

抓出dump,然后分析。别空对空,总要有实际证据

1.对象用完释放
2.查看看是不是有不合理的sql,比如查询一个大型数据集把全部数据加载到内存,优化sql

抓出dump,然后分析。别空对空,总要有实际证据

1.首先托管内存的运行库采用的是垃圾回收器来回收的方式。垃圾回收器本身也是一个程序。程序动态请求的内存都分配到堆上,在.net中,CLR维护它自己的托管堆供.net程序使用。每隔一段时间.net就会检查托管堆,当检查到需要清理堆时,.net就调用垃圾回收器这个程序。垃圾回收器会扫描堆上的对象的引用,不再有引用的对象就被删除。垃圾回收器调用的时间是不确定的。所以我们在编写代号时尽量首动释放对象。还有程序自行调用垃圾回收(System.GC.Collect()).
2.非托管内存,回收器是不知道如何释放非托管资源,如文件句柄,网络连接、数据库连接等。当非托管对象被托管对象引用时,托管对象被释放时应确保其相关的非托管对象被释放。自己可以看看非托管内存的管理
3.反射的内存占用,曾经我做过一个程式,就是定时执行反射,系统也是用了一段时间就内存不足,解决反射内存占用,需要用到域的管理,动态卸载被反射的dll

Winform确实不适合做大一点的商业软件开发。。不然呢我也认为Winform确实是很方便做桌面的。。为什么那些大些商业软件不选择Winform呢?如photoshop, CorelDraw, UG,PRO/E,AutoCad真的方便功能强大这些软件早就用Winform改写了,你说是不是呢?

借助这个帖子请教一下,我们公司有一个服务器放的web项目在运行的,服务器重启之后运行IIS,查看内存只占用了十几G,过了一个星期左右就跑到接近30G了,这也是因为资源未释放的原因吗?

内存不足很多情况是用了太多的dataset,除了界面需要绑定表格的dataset,其他查询功能换成查询sql试试。
总之就是尽量少用dataset。

首先优化自己代码,如果没怎么优化过的人,可以借助一些性能分析工具,如JetBrains dotTrace,NET Memory Profiler等,我曾经也用过,蛮好用的,另外可以自己写一个应用池监控服务,定时的回收。另外特别注意是否用到反射之类的功能,如果有,就要注意了

如果你一时半会没法找出问题, 那就把消耗内存的功能操作写成一个个 .exe 文件。
WinForm 只是当界面用用, 需要什么功能就用 proccess 调用哪个 .exe , 用完进程就自动结束了, 你的代码写的好与坏也没大关系, 反正用完就结束, 不存在累积的问题。
按我的做, 保证你连续用两年没问题。

还是查代码吧,所有的循环里new出来的东西都记得杀掉。

估计是调用啥api然后没给释放,例如gdi之类的

C#从数据库查找记录输出问题
解码问题,试了所有方法,都不能解码,请问为什么
获取目标主机时间(C#)
下面B的结果是多少? 定义变量有没有static到底有什么关系?
怎样封装自定义Button控件的MouseEnter事年和MouseLeave事件
使用VS2003的问题,新建属性对话框空白,有人遇到过吗?
.net环境下用c#写的程序如何发布才能在wince平台上运行
请大家详细介绍一下关于Socket传送文件的方法,给个简单完整的例子!巨分相送!
01cn 精华(2003--2004,含软件工程,Delphi,java等等,请大家帮忙提前)
获取远程计算机DNS名的问题
timer.stop()和try/catch的问题
新人求助,VS2017无法调试,代码没问题,就是调试报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值