社区
网络通信/分布式开发
帖子详情
最近用对完成端口做的服务器程序做压力测试,发现服务器的内存慢慢减少:(
LittleStar
2006-04-23 09:49:22
客户端用asynselect,一收到服务器的消息就立即发送数据给服务器。中间没有暂停,此时服务器的内存会慢慢减少。如果客户端暂停发送与接收,服务器的内存又会慢慢增加,再接着发送数据服务器的内存又慢慢减少。
请问为什么服务器会产生这样的问题?该如何解决。
...全文
663
11
打赏
收藏
最近用对完成端口做的服务器程序做压力测试,发现服务器的内存慢慢减少:(
客户端用asynselect,一收到服务器的消息就立即发送数据给服务器。中间没有暂停,此时服务器的内存会慢慢减少。如果客户端暂停发送与接收,服务器的内存又会慢慢增加,再接着发送数据服务器的内存又慢慢减少。 请问为什么服务器会产生这样的问题?该如何解决。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
11 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
leaber
2006-04-29
打赏
举报
回复
竟然写错了,异步每次投递一个请求都是要分配新的内存的 应该是每一个新的连接都是要分配新的内存块。
leaber
2006-04-29
打赏
举报
回复
CPU占用率高吗? 异步每次投递一个请求都是要分配新的内存的,如果没及时发送还会发生内存锁定的情况。查一下,只要没有内存泄露就好了。
另,不知道你是否开内存池?频繁的创建内存块会产生内存碎片的,然后稳定性就是个问题了。
constantine
2006-04-29
打赏
举报
回复
学习一下,不太会,只看过一下
LittleStar
2006-04-25
打赏
举报
回复
哎,不清楚怎么写。
昨晚又做了一个简单的wasAsynSelect的客户端进行测试。服务器端是最简单的iocp server。发现连续不断的测试,并没有导致服务器端的内存减少。看来要好好调试一下原来的服务器端程序了。
客户端用send recv连续发送和接收,过一段时间就会堆栈溢出。后来换成wsasend wsarecv就再也不会出现堆栈溢出。
飞天揽月
2006-04-24
打赏
举报
回复
不错,学习!!!
bluesky23
2006-04-24
打赏
举报
回复
UP
shadowfish
2006-04-24
打赏
举报
回复
关注中,最近也在研究完成端口
clasj
2006-04-24
打赏
举报
回复
我觉得你找到的那篇文章说的已经很清楚了,你试过没有啊?
LittleStar
2006-04-24
打赏
举报
回复
没人做iocp吗?
深宇
2006-04-23
打赏
举报
回复
能否贴一些关键性的代码上来,不然别人怎么帮你解决问题呢?
LittleStar
2006-04-23
打赏
举报
回复
搜了一下,发现有文章可能会有帮助,可是我对完成端口粗通皮毛。实在搞不清楚具体的实现方式。
(引自flashboy (爱写程序的小绵羊) )
一、 WSAENOBUFS 错误问题。
这个问题通常很难靠直觉发现,因为当你第一次看见的时候你或许认为是一个内存泄露错误。假定已经开发完成了你的完成端口服务器并且运行的一切良好,但是当你对其进行压力测试的时候突然发现服务器被中止而不处理任何请求了,如果你运气好的话你会很快发现是因为WSAENOBUFS 错误而影响了这一切。
每当我们重叠提交一个send或receive操作的时候,其中指定的发送或接收缓冲区就被锁定了。当内存缓冲区被锁定后,将不能从物理内存进行分页。操作系统有一个锁定最大数的限制,一旦超过这个锁定的限制,那么就会产生WSAENOBUFS 错误了。
如果一个服务器提交了非常多的重叠的receive在每一个连接上,那么限制会随着连接数的增长而变化。如果一个服务器能够预先估计可能会产生的最大并发连接数,服务器可以投递一个使用零缓冲区的receive在每一个连接上。因为当你提交操作没有缓冲区时,那么也不会存在内存被锁定了。使用这种办法后,当你的receive操作事件完成返回时,该socket底层缓冲区的数据会原封不动的还在其中而没有被读取到receive操作的缓冲区来。此时,服务器可以简单的调用非阻塞式的recv将存在socket缓冲区中的数据全部读出来,一直到recv返回 WSAEWOULDBLOCK 为止。
这种设计非常适合那些可以牺牲数据吞吐量而换取巨大并发连接数的服务器。当然,你也需要意识到如何让客户端的行为尽量避免对服务器造成影响。在上一个例子中,当一个零缓冲区的receive操作被返回后使用一个非阻塞的recv去读取socket缓冲区中的数据,如果服务器此时可预计到将会有爆发的数据流,那么可以考虑此时投递一个或者多个receive来取代非阻塞的recv来进行数据接收。(这比你使用1个缺省的8K缓冲区来接收要好的多。)
总结:
解决方法一:
投递使用空缓冲区的 recevie操作,当操作返回后,使用非阻塞的recv来进行真实数据的读取。因此在完成端口的每一个连接中需要使用一个循环的操作来不断的来提交空缓冲区的receive操作。
解决方法二:
在投递几个普通含有缓冲区的recevie操作后,进接着开始循环投递一个空缓冲区的recevie操作。这样保证它们按照投递顺序依次返回,这样我们就总能对被锁定的内存进行解锁。
C++手搓Web
服务器
:从Socket到epoll,掌握高性能网络编程核心
网络编程是现代服务端开发的基石,其核心在于高效处理大量并发连接。I/O多路复用技术是实现这一目标的关键,它允许单个线程监控多个网络连接的状态变化,从而避免为每个连接创建独立线程的开销。在Linux环境下,epoll作为高性能的I/O事件通知机制,通过事件驱动模型显著提升了高并发场景下的处理能力。结合Reactor模式,可以将事件监听与业务逻辑解耦,构建出清晰且高效的服务架构。这种技术组合对于构建低延迟、高吞吐的在线服务具有重要价值,广泛应用于实时通信、API网关和微服务等场景。本文以C++实现一个Web服务
Linux C/C++实战进阶:60个项目打通高薪后端开发核心技能
在系统级编程领域,Linux C/C++是构建高性能、高并发服务的基石。其核心原理在于通过直接调用操作系统API,实现对硬件和系统资源的精细控制,从而在底层网络通信、
内存
管理和多线程并发等方面获得极致性能。这项技术的核心价值在于能够开发出高效、稳定且资源占用低的系统软件、中间件和
服务器
程序
,是搜索引擎、分布式存储、游戏
服务器
等对性能有严苛要求场景的首选。为了掌握这项硬核技能,实践是关键。通过系统性地
完成
一系列由浅入深的实战项目,例如从实现基础命令行工具到构建多线程HTTP
服务器
、
内存
池乃至轻量级RPC框架,
接口测试中500错误排查全攻略:从原理到实战的完整解决方案
在软件开发和测试领域,HTTP状态码是理解网络通信的基础概念。其中,5xx系列状态码代表
服务器
端错误,而500 Internal Server Error作为最常见的
服务器
错误响应,其背后往往涉及复杂的系统交互逻辑。从技术原理层面看,500错误的产生通常源于
服务器
在处理请求时遇到了未捕获的异常或内部故障,这可能是代码逻辑缺陷、资源依赖异常或配置错误等多种因素导致。理解这些底层机制对于构建稳定的软件系统具有重要价值,特别是在自动化测试和持续集成场景中,快速定位和解决500错误能显著提升交付效率和质量。在实际应
C++线程池实现详解:从原理到TinyWebServer高并发优化
线程池是一种核心的并发编程模型,其原理在于预先创建并管理一组线程,通过任务队列实现任务的提交与调度。这种技术能有效避免频繁创建销毁线程的系统开销,显著提升程序的资源利用率和并发处理能力,在
服务器
开发、数据处理等高性能场景中价值巨大。本文聚焦于C++11标准库实现,深入解析了线程池的任务队列、线程同步机制与优雅关闭等关键设计,并探讨了其在TinyWebServer项目中的应用,通过引入线程池解决了高并发下的性能瓶颈问题,为构建稳定高效的网络服务提供了工程实践范例。
告别双系统:在Windows 11上无缝体验Ubuntu 24.04的完整指南
本文详细介绍了在Windows 11上无缝体验Ubuntu 24.04的完整指南,通过WSL2技术实现双系统功能的完美融合。文章对比了WSL2与全盘安装方案的优缺点,提供了图形界面配置、开发环境搭建及性能优化的实用技巧,帮助开发者高效利用Ubuntu开发环境,同时享受Windows的便利。
网络通信/分布式开发
1,594
社区成员
32,944
社区内容
发帖
与我相关
我的任务
网络通信/分布式开发
Delphi 网络通信/分布式开发
复制链接
扫一扫
分享
社区描述
Delphi 网络通信/分布式开发
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章