2011-10-31 第一天测试,客户端蹦了1000多次。因为之前没有任何的异常处理,最近在游戏主程序入口添加了异常捕获,检测到异常即弹出BUG提交报告,结束客户端进程。此方法导致客户端崩溃次数过多,需要做处理,以后在做开发的时候,每个函数需要做异常捕获,可以参考天龙的代码。服务器第一天还算稳定,基本没有出现崩溃的现象。
2011-11-01 第二次测试,客户端根据收集的信息,更改了崩溃导致的BUG,而服务器蹦的稀里哗啦的,首次由于组队拾取分配的时候导致崩溃,具体原因是溢出,仅接着又出现了物品复制的问题,再次导致了服务器的崩溃。另外服务器内存一直异常增长。半小时后再重新开的。实际测试不到一小时。
2011-11-03 今天查出了服务器内存增长的部分原因,一是自实现的一个HASH数据结构,内存使用calloc进行分配,却使用了DELETE释放,此文件使用了2年多,居然没发现,汗一个;另外一个重要的原因是在AI中,怪物进行追击的时候,不断的在重设追击目标,每帧发送的数据包量太大,导致网络层处理不过来,导致内存猛涨,起起落落,当没有足够内存分配时,服务器便挂了。主要就这些了,期待今天晚上的测试吧。
2011-11-08
03号没有再进行测试,因为内存一直增长,扛不了多久,周末找了外援,推荐了glowcode工具来检测泄露。有经验还是不错滴。省很多事,不需要再次摸索。
今天号称是第二轮测试,希望会比之前的2次要好!
在查询内存的时候,采用了glowcode工具来检测,初次使用,仅仅关注需要的功能。
STL本身并没有什么问题,但是如果使用不当,很容易导致内存泄露。
区域服务器使用了类似空闲列表的技术,使用后回收,下次使用从空闲列表中取数据。如果在回收的结构中使用了STL的
数据结构,并大量的push_back操作,回收或者复用的时候仅仅是调用clear 方法,很容易会发现,内存涨的很厉害。
于是,把代码样本抽出来,如下:
#include "TObjectPool.h" #include <vector> class CObject { std::vector<int> v1; public: void test() { for (int i = 0; i < 1000; ++i) { v1.push_back(i); } v1.clear(); #if 0 // if not do this, memory leaks. std::vector<int>(v1).swap(v1); #endif } }; void TObjectPoolTest() { #if 1 CObjectPool<CObject*>* pObjPool = new CObjectPool<CObject*>(sizeof(CObject)); for (;;) { CObject* pNewObject = pObjPool->AllocaObject(); memset(pNewObject,0,sizeof(CObject)); pNewObject->test(); pObjPool->ReleaseObjdect(pNewObject); ::Sleep(10); } #else for (;;) { CObject* pNewObject = new CObject; if (pNewObject) { pNewObject->test(); ::Sleep(10); delete pNewObject; } } #endif }
第一列数据是访问次数,图一为执行std::vector<int>(v1).swap(v1);操作的结果,图二为没有执行的结果。可见没有执行的调用malloc的次数要多的多,实际上是一直在调用,而图一为刚开始调用,后面就不再调用了。当然,这个只是在使用了TObjectPool的情况下,正常情况下没有出现。
测试结果:
整个测试过程中上线保持在300~400的区间,服务器还算稳定,没有再出现崩溃的现象,不过内存还有小额度的增长,还有未解决的内存泄露问题。一直持续到9点,往上累加机器人,直到1500左右,此时占用内存1.4G,带宽发送约2.8M*8,接收带宽约0.7M*8.平均每个玩家15.2K。