qt界面崩溃与假死问题
来源:互联网 发布:清除文件 linux 编辑:程序博客网 时间:2024/05/16 11:22
在开发图表项目时,项目要求如下:
同时打开100多个图表,单个图表的数据5W左右,结果图表出现了崩溃与假死的现象,每天好几次,不是必定出现现象,有的电脑未出现,有的电脑出现频繁
尝试了以下方式去解决问题:
首先出现了崩溃的现象
1.认为是历史修改代码导致,则通过svn查看历史版本的log,注释掉关键的代码继续测试
仍然崩溃
2.猜测是指针或者内存使用问题,则利用dbughelp配置在项目中,在用户环境测试,果然生成了dump文件,根据dump文件,修改了多线程使用内存的问题
仍然崩溃
3.但是此时不再生成dump文件,此时引入了压力测试,socket每秒发送1W~10W的数据,只有检查代码信号量的地方,发现list的append 和takefirst并不是线程安全的,果断加上锁
仍然崩溃
4.认为写文件线程可能存在问题,果断将写文件的线程从while循环改成moveToThread线程的方式,这样线程不需要使用锁了,通过信号槽实现传递数据
此时,界面不再崩溃,却出现了假死,即界面的图表不再更新,鼠标点击无响应,关闭发送数据,等待多久仍然假死,只能通过任务管理器结束程序
5.此时开始进行大量的压力测试,发现只开一个图表时,图表仍然会因为每秒10W的数据假死,图表描画一次的世界大约18ms,这个时候我们认识到GUI线程的描画能力有限,不可能同时或者连续的更新100多个图表,于是我们将图表对象存储管理起来,一个个描画,每描画一个,则用qApp->processEvent()让主线程去处理post事件或者系统事件而不是一直忙着描画事件,这里qApp->processEvent()有个潜在的风险需要注意:如果qApp->processEvent()所处的循环在读写内存,而在主线程处理其它事件时也访问了该内存,可能造成读写异常,所以qApp->processEvent()的范围和对内存的操作需要特别注意,并且限定每一个图表的最大数据量为10W
6:利用qdebug打印log记录到文件,图表却卡的更频繁,发现高频使用qdebug非常消耗性能,则去掉该方法
仍然假死,并且发现程序的内存会在某一时刻突然增加,增加到1.8G左右,然后界面假死
7.认为可能是写文件线程仍然可能存在问题,优化,从程序要写400左右个数的文件减少到300个左右,并且每个线程各写150个左右,减少文件的IO操作,文件不再不停打开关闭,把文件的指针存储管理起来,一开始打开,程序结束时关闭,并且调查了windows同时可以打开509个( 512-3)
8.开始使用内存泄露检测工具检查程序,后来发现作用甚微
仍然假死
9.这个时候只能换个角度思考了问题,采用了两个工具开始监控程序的cpu和内存使用记录,其中一个为windows性能监视器,发现程序在某一时刻内存会飙升
10.为了提高程序性能,尝试了批量发送数据和批量接收数据,批量发送数据和单个发送数据相比,内存差异不大,cpu降低5%
11.认为自己写的程序不再有内存泄露,那是不是QT的问题呢?或者没有用好QT呢? 答案是肯定的,我们开始猜测是信号量的问题,因为信号量跨线程在不断的拷贝,这个时候进行了demo程序测试,所谓demo程序就是一个线程负责发送数据,一个线程接收数据,尽量简单,发现当两个线程的处理为空时,一秒放松百万信号,程序运行正常,因为QT的每秒信号量处理数约为600W左右,但是只要接收线程对收到的数据进行一点数据处理,如QString::number,实际测试大约每接收一次数据,有50次左右的QString::number,发现界面果断卡死,这个时候真相快要大白了,界面假死原因可以理解成信号量阻塞了,利用windows api 打印cpu轮转,计算前面50次左右的处理时间,约为0.15ms,显然,生产者速度过快,消费者处理较慢就会阻塞
真相大白:生产者和消费者的速度不匹配导致了图表假死,解决办法:将消费者的部分数据处理移到生产者中,相当于间接的适当的阻塞一下生产者,并且提高消费者的速度,这样,生产者和消费者速度匹配。就解决了界面假死的问题
赠送名言:你在乎的人越多,你就越脆弱
- qt界面崩溃与假死问题
- 解决C#界面假死问题
- QT GUI界面假死的处理
- QT GUI界面假死的处理
- Qt 界面刷新崩溃、异常
- 使用pthread后,界面假死现象问题
- java gui 多线程,界面假死、僵死问题
- QT多线程网络编程程序崩溃问题与解决
- 关于session未能正常关闭造成界面假死的问题
- C#多线程与UI响应 防界面假死
- C#多线程与UI响应 防界面假死
- C#多线程与UI响应 防界面假死 .
- VS2008设计界面假死
- 多线程编程界面假死
- C# 界面假死
- C#-界面假死
- c# 界面假死
- winform 防止界面假死
- windows 如何下载到Anaconda Python
- 文件的创建与删除
- 【备忘】开发Android移动互联网应用视频 下载
- jQuery animate() 自定义的动画。
- Boost.Asio入门
- qt界面崩溃与假死问题
- [LCT 边双连通分量缩点] BZOJ 2959 长跑
- leetcode_326. Power of Three
- Android Webview中解决H5的音视频不能自动播放、只有声音没有图像的问题
- json.stringify和json.parse,序列化和反序列化
- 289. Game of Life
- PE文件结构详解--PE导出表
- 【Java 简介】
- 每天一个 Linux 命令(6):rmdir 命令