《诸子百家》发布后,发现游戏在有些情况下会崩溃。偶然崩溃。

由于我是负责主框架,网络协议和登录,数据等,所以这个修正bug的任务主要就落在我头上了。

一、bug

1.最头疼的bug

HEAP: Free Heap block xxxxxxxx modified at xxxxxxxx after it was freed

这个是最头疼的。知道崩溃了,知道内存地址,但是不知道在哪个文件。跟踪了好几天,打了很多日志,没头绪。后来网络上一找,也有很多人碰到这个问题。主要的解决方案是下载使PageHeap.EXE或GFlags.EXE检查内存越界错误,还有就是用WinDbg.

于是屁颠屁颠的把这些都下下来,搞了一阵子,发现不实用。主要是我们游戏里面,代码文件还是蛮多的,300多个文件,代码行估计有20万行~ 这个里找错误还真不好找,工具也没办法定位到具体的文件。

想了很久,后来觉得自己把问题想的太复杂了。

上面的错误很典型的就是内存已经被释放了,后面还继续使用。简单点说就是野指针!而造成野指针的原因很简单,就是内存被释放了。

于是,问题变简单了:找出所有释放内存的地方。

释放内存的,主要就2个:free和delete.

于是,我使用了2个宏,S_DEL(p) if(p){delete p; p=NULL;}

S_FREE(p) if(p){free(p); p=NULL;}

然后把所有用到这两个的地方都用宏替换掉,然后再把这两个宏里面真正释放的给注释掉。再跑,发现很OK,不会崩溃了。 于是,确认了是释放引起的。

然后在逐个把两个宏里的释放打开,发现打开S_FREE没问题,于是范围缩小到S_DEL里了。然后再把S_DEL里的释放也打开,再按照模块,把可以的地方用到的那个S_DEL注释掉~~ 这个样折腾了好久,最终找到了bug

2. 郁闷的bug

有时在团战的时候,发现打到一定阶段,程序就崩溃了。查看内存,看起来也没什么特殊的。。。

然后也是很长时间的排查。。。。。

二.具体总结

1. 经过很久的排查和使用上面的方法后,终于把这些崩溃点都解决了。主要有3个bug:

1).AMF3协议里面。我们使用独立的内存分配器进行内存的分配和释放,保证不内存泄漏。内存不泄露这个目标是达到了,但是有时把正在用的内存给释放掉了,造成了野指针。

为什么会把正在使用的内存给释放掉了呢?原来,在AMF3里,有一些数据是用引用的方式,而我们进行功能改写时,使用了同样的引用的方式,造成了多个节点使用同一个内存,因此导致其中某一个节点把这内存释放后,其他使用这个的都变成野指针了。

解决方案:不要使用引用,每个使用独立的内存

2)战斗里面,我们有一些战斗进度是用OnRender进行驱动的。比如A含有5个B,B含有10个C,我们的战斗进度的驱动之一是是C的OnRender()。而OnRender是一直循环调用的,用这进行驱动的时候,如果符合了某一个条件,比如战斗结束,那C通知B,B通知A,A就释放内存,通知结束。这种模式的问题是,A释放内存后,C返回到战斗结束的触发点继续运行就崩溃了~

解决方案:检测到战斗结束时,要所有的模块退出OnRender,然后才释放内存~

3)用户注销重新登录时,有时崩溃。

原因是用户注销时,我们会把所有的内存释放掉,把socket关闭。但是可能我们把内存释放掉时,由于socket还在,所以继续收到数据包进行AMF3的解析,而解析结果已经部分被清掉了,这个时候访问,野指针,崩溃~~

改成先把socket关闭,然后内存再释放掉。发现,有时还是会崩溃~~ 后来发现,因为我们的socket是单独线程处理的,也就是说我们释放内存和关闭sockt的操作是在2个线程里处理,这样总会出现一个先,一个后的,如果释放内存比关闭socket先执行,则还是会出现野指针。

解决方案:在socket线程里进行socket的释放,等socket释放完毕才进行内存的释放~

转载于:https://www.cnblogs.com/Anzhongliu/p/6091768.html

HEAP: Free Heap block xxxxxxxx modified at xxxxxxxx after it was freed相关推荐

  1. 调试异常 Free Heap block xxxxxxxx modified at xxxxxxxx after it was freed

    方法一:如果你是C++程序员,如果你写过一个很复杂的程序,如果你经常碰到莫名其妙的崩溃问题.那么你就有可能遭遇了野指针.如果你比较细心,注意了Debug output输出窗口的话,那么你就有可能注意到 ...

  2. Free Heap block XXXXXXXX modified at XXXXXXXX after it was freed

    Free Heap block XXXXXXXX modified at XXXXXXXX after it was freed,C++报出这个错误,这个BUG是堆溢出错误,意思是程序修改的堆空间在之 ...

  3. HEAP: Free Heap block XXXX modified at XXXX after it was freed

    开发过程中,有时候会遇到堆异常的情况 这时,VS的调试输出窗口会提示: HEAP[MemTest.exe]: HEAP: Free Heap block 39b998 modified at 39b9 ...

  4. HEAP: Free Heap block XXXX modified at XXXX after it was freed详解

    测试代码: char* testP(char*pfuck) { static char chardd[123]; strcpy(chardd,pfuck); delete pfuck; return ...

  5. HEAP: HEAP: Free Heap block xx modified at xxafter it was freed 堆内存出现野指针错误

    首先看下问题提示: HEAP[SimEng.exe]: HEAP: Free Heap block 000002CA51FC08A0 modified at 000002CA51FC0950 afte ...

  6. Memory Analyzer Tool 1 Shallow heap Retained heap dominator tree(控制树)

    文章目录 1. shallow heap 2. retained heap 3. dominator tree(控制树) 1. shallow heap 引用原文介绍 :Shallow heap is ...

  7. GFlags 使用详解

    GFlags - 老牌的PageHeap配置工具,有命令行和GUI两种操作方式,功能比较全,包含在Windbg调试器安装包内.同样在Windows 2000 Professional SP2 以上可用 ...

  8. GFlags调试堆中野指针

    我个人觉得写代码最悲哀的就是,程序的出错结果往往出人意料,并不在自己预期的错误列表中,其中堆中的野指针就是一个很隐蔽的问题.记得之前写了一个模块,后来因为功能升级,而修改了部分接口,等到运行的时候,老 ...

  9. C++ 内存泄漏调试

    C++和其他高级语言不同,需要自行管理内存,项目大\调用多,容易内存泄漏.内存申请释放使用malloc/free和new delete两种方式. 当内存报错弹出一个陌生的地址,我一脸懵逼,不清楚是哪个 ...

最新文章

  1. 【运筹学】线性规划 单纯形法 ( 基矩阵 | 基变量 | 非基矩阵 | 非基变量 | 矩阵分块形式 | 逆矩阵 | 基解 | 基可行解 )
  2. 详解虚函数的实现过程之菱形继承(5)
  3. oracle直方图基数,等频率直方图计算基数
  4. Java自动生成增量补丁自动部署_java-Hibernate正在为表生成自动增量交替ID
  5. Spark之RDD实战2
  6. vs2015调试时不显示vector内容的解决方法
  7. kotlin和python哪个好_python替代品for一些java及kotlin功能(慎入啊慎入)
  8. 简单的Verilog测试模板结构
  9. 翻译 Windows Server 2016和System Center 2016 技术预览版4 使创新更容易
  10. Java:String和Date、Timestamp之间的转换
  11. 每天一道算法题(16)——翻转链表
  12. 28个极简代码——python
  13. 《SSCOM串口/网络数据调试器》
  14. 矩阵的逆矩阵 和 转置矩阵
  15. 【机器学习】左逆、右逆、伪逆和广义逆的概念理解
  16. 开源让这位 00 后逆袭成为各类大奖收割者
  17. linux自动联想,在联想扩展坞和Linux上自动切换显示
  18. 随机生成数猜大小(java实现)
  19. Linux面试题汇总-2
  20. 人生不同年龄阶段该怎么买保险?

热门文章

  1. 是时候详细探究webview了
  2. Android 性能优化:使用 Lint 优化代码、去除多余资源,减少APP的size
  3. linux 虚拟文件系统 源码,Linux内核源代码情状分析-虚拟文件系统
  4. mediasoup 安裝
  5. 示波器纹波测试的时间设置_500W电源横评:输出纹波3款电源超标
  6. [大学回忆录]桂X大学大二(上)学期总结
  7. Jsoup获取动态js生成的内容
  8. 拉普拉斯变换_拉普拉斯变化(s变换)定义与性质
  9. docker-compose 配置kafka_Docker Compose 引用环境变量
  10. 【kudu】未解决 Flink 读取 kudu KuduReaderIterator not found it may have expired