diff --git "a/\347\211\210\346\234\254\345\216\206\345\217\262.md" "b/\347\211\210\346\234\254\345\216\206\345\217\262.md" index 8e3ef7e..95338c5 100755 --- "a/\347\211\210\346\234\254\345\216\206\345\217\262.md" +++ "b/\347\211\210\346\234\254\345\216\206\345\217\262.md" @@ -66,4 +66,5 @@ > - 添加静音功能 > - 修复Mysql连接超时问题带来的程序崩溃问题 > - 修复多人进入同一房间的BUG +> - 修复内存泄漏及服务器易崩溃问题,可以实现上万级房间数的并发PK > - 修复了一些BUG \ No newline at end of file diff --git "a/\351\201\207\345\210\260\347\232\204\345\233\260\351\232\276.md" "b/\351\201\207\345\210\260\347\232\204\345\233\260\351\232\276.md" index 458dc2f..16c3090 100755 --- "a/\351\201\207\345\210\260\347\232\204\345\233\260\351\232\276.md" +++ "b/\351\201\207\345\210\260\347\232\204\345\233\260\351\232\276.md" @@ -22,4 +22,7 @@ - 解决办法是:客户端的请求都加上一个终止标志位,服务器在接收到一长串请求消息时,根据这个终止位来拆分不同的请求,将这些请求消息存放到一个容器中,最后,再从容器中依次取出请求消息来做出响应。 3. 长时间(1天以上)不连接服务器,再次连接,服务器会发生崩溃? - 通过生成core dump文件,运用gdb调试core dump文件,发现崩溃的原因是程序收到了SIGSEGV信号,出错的位置在mysql_fetch_row ()函数调用时,发现是在mysql_query()函数执行出错时,调用mysql_store_result()会返回NULL,此时再调用mysql_fetch_row ()就会发生段错误。然后,又考虑为什么只有1天后再次连接服务器会报错,重启服务器后,再次连接一切正常?最后,考虑到可能是mysql有超时机制,长时间没有查询请求后,会自动关闭连接,结果在网上一搜真的是这样:Mysql默认连接超时时长为8小时,无查询请求8小时后,Mysql会自动关闭连接,此时再调用mysql_query()函数,就会执行失败 - - 解决办法有两种:第一种是,修改Mysql配置文件,将超时时长设置为最大值31536000s=1年,但这种解决方法并不完美,终究会超时。第二种解决方法是,在调用mysql_query()函数失败时,如果失败返回的错误码为CR_SERVER_LOST,则代表服务器不可用,Mysql服务器断开了超时的连接,此时再调用mysql_real_connect()重连一下Mysql服务器,再执行查询,就能查询成功了 \ No newline at end of file + - 解决办法有两种:第一种是,修改Mysql配置文件,将超时时长设置为最大值31536000s=1年,但这种解决方法并不完美,终究会超时。第二种解决方法是,在调用mysql_query()函数失败时,如果失败返回的错误码为CR_SERVER_LOST,则代表服务器不可用,Mysql服务器断开了超时的连接,此时再调用mysql_real_connect()重连一下Mysql服务器,再执行查询,就能查询成功了 +4. 测试过程中发现,不能支持多个玩家同时匹配游戏,服务器存在崩溃以及内存泄漏的问题? + - 通过调试core dump文件发现,崩溃的原因是内存用完,出现bad_alloc异常,发生在splitRequestMsg函数中。最开始,认为是存放客户端请求信息的RqMsgList数组,在处理完消息后,没有释放内存导致的,结果在每次处理完毕后,调用shrink_to_fit,也不能解决崩溃问题,后来又考虑是不是vector分配内存时两倍扩容的机制导致的问题,把vector换成了deque,也没有解决问题。最后考虑可能存在死循环,让RqMsgList一直在申请内存,导致内存用完,最后发现在拆分请求字符串时确实存在死循环的可能,修改后,bad_alloc异常不再出现 + - 虽然服务器不会出现bad_alloc异常而崩溃了,但是在测试的过程中,却发现了内存泄漏问题。每次测试200左右房间数的对战,内存总是会被占用2M左右,而且在服务器处理完毕后,也不会释放。最开始考虑到,可能是在堆上申请内存的对象,在使用完毕后,没有释放内存导致的,但是一行行检查代码时,没有发现这个问题。后来想借助内存泄漏检查工具valgrind来检测内存泄漏的位置,但是valgrind不支持muduo库的一些语法,不能检测。然后,就想着在请求信息处理函数onMessage中,一行行的注释,每次去掉一些功能,去掉一些处理的逻辑,再测试看有没有内存泄漏的现象。因为内存泄漏发生的很快,也很容易出现,所以就定位到问题出在编解码器的处理函数deCodeMessage中,在deCodeMessage中用相同的办法,定位到了Mysql类中的Register函数,在Register函数中用相同的办法,终于定位到了内存泄漏的罪魁祸首-mysql_store_result与mysql_free_result,当保存了查询结果后,必须释放,不然mysql申请的用来保存结果的内存就不能被释放,也不能被再次使用,从而导致内存泄漏。定位到这个问题后,发现之前写的代码中,很多函数都有类似的问题,修改后,内存泄漏问题解决了。 \ No newline at end of file