存在内存泄露
tpc 服务,和客户端直接连接; 压力测试 几百个,就可以造成内存泄露; 后面的人连接不上了,连接都是 删除连接的操作;
PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAN 20 0 2057m 1.8g 2432 S 0.3 24.2 0:27.78 gate_service
这个服务仅仅是个转发消息的。仅仅压力测试几百就可以造成这种后果
内存是缓慢增长上去的,感觉像是在删除 socket 哪块出的问题
这个问题只存在linux上,win上是正常的; 2个服务进程tcp 的; 直接占用50%内存; 同时不会再接收连接
谢谢你的反馈。
- 库只会用stl对象,或者boost对象,没有创建并维护过指针,这意味着想内存泄漏都有一定难度。
- 请详细描述你是怎么做压力测试的,或者提供代码,比如到底是不停的连接断开再连接,还是发送尽可能多的数据占满带宽。
- 查看object_pool::size()和object_pool::invalid_object_size()的大小。
- 对于主动关断连接的一方,套接字会进入TIME_WAIT状态,并持续一定的时间,在这段时间之内,这个端口将不可用,如果服务器机器上所有端口都处于这个状态,则无法接收新的连接,这是SOCKET的设计,可以通过参数修改这个行为以及持续时长。
- server_base默认最多支持4096个连接,当多余的连接到达时,会主动关断连接。
- glibc是有内存池的,一般只增长不减小。
- 每个st_asio_wrapper::socket都有两个消息缓存,每个缓存里面最多1024条消息(消息长度要看解包器),和一个解包器,占用4000字节宝长长度。这些都是默认值,可以被修改。
比如到底是不停的连接断开再连接 , 这种情况居多; 刚开始做的压测工具不标准,有点像个攻击工具。有自动重连。 刚压力测试完内存也基本没什么变化。那会也是能用其他的工具登录进去。 过一小会,内存就会不停的增长,2个和客户端有连接进程,可以占服务器内存的50%;
一个gate 是转发数据的额,一个是login 。login 登录后就会断开连接,后期服务不再使用login而是用game
正常点压测工具马上就出来了,再试试。- - 对作者说声谢谢哈
我们的内存对象管理,现在都是自己 手写的。应该不会这里的原因; 多个服务进程是同一套,底层网络服务。其它的都正常。只有与客户端有连接是这样的。
有一种情况,就是压测工具的机器人关闭了。不施放socketfd 套接字。 客户端unity等杀进程是能关掉的。 对于这种情况。我应该怎么处理下。 如何直接施放压测工具直接关闭的情况(不走del_client 接口)。
或者服务端,如何,控制,清楚哪些断开的连接,。
异常断线是检查不了的,所以才有了心跳包的出现(但你这种情况不能开启心跳包功能,因为对方不是st_asio_wrapper库,心跳包是用户数据包,必须两端都认可的格式才能叫心跳包)。 默认情况下,只要你不截获on_recv_error,框架会走del_socket(这个签名跟你的不一样,可见你没有用最新的版本,建议用最新版本),除非你定义了ASCS_CLEAR_OBJECT_INTERVAL且大于0,此时框架会帮你定时批量清理无效的socket,所谓清理其实是放object pool里面等待被重用,如果不想被重用,就不能定义ASCS_REUSE_OBJECT或者ASCS_RESTORE_OBJECT宏,那么才会真正的从内存中释放socket。
异步通信系统里,释放对象是很麻烦的一件事,搞不好会造成回调的时候,对象野掉了。 object_pool::invalid_object_size()就是断开的连接的数量,没有真正从内存中释放(原因可能是开启了对象重用,或者异步调用还未结束所以不能释放)。 object_pool::size()是有效(包括未检测到的断开了的连接)连接的数量。
注意,上面我说的宏是ascs库用的,st库的话,把前辍改成ST_ASIO_,同时我也建议你用ascs,效率远高于st库,ascs需要c++0x,不需要boost,st库需要boost不需要c++0x,st库的接口与ascs完全一样,只是顶层命名空间一个是st_asio_wrapper,一个是ascs,其它都一样。
多谢作者:我试试你说的换个库把