Winsock服务器内存资源管理

来源:互联网 发布:淘宝退款小二介入 编辑:程序博客网 时间:2024/05/16 04:40

        一般来讲, 在服务器上,如果有足够的资源,Winsock server,理论上可以支持成千的并发连接。而现实是,我们没有足够的资源可供使用,分配。本文主要来讨论一下内存资源之于Winsock server开发的重要性。 一)基本概念。 -> Pages,Locked Pages.         在现代操作系统中,内存管理会把主存(RAM)分成Pages来管理。 Paging(或者swapping)指的是主存与外存之间以Page为单位进行数据的交换。Locked Pages指的是被锁定在主存中的内存页,以保证一些内核组件,driver可以访问到它们。windows一定会保证一定数量的可交换的内存空间,防止一些非法程序锁定所有的物理内存,而致使系统崩溃。在windows NT, windows 2000上,可锁定的内存总的大小上限大概是物理内存的1/8(当然对于程序的开发人员,不应该对这个值进行任何的假设,这个值可能会随着操作系统本版的变化而变化)。在Winsock应用开发过程中,以overlapped方式读写IO操作,将会导致内存被锁定。 -> working set         在程序开始运行,并达到其稳定的运行状态(主要指的是其对内存的使用),在这个状态下,程序使用内存的数量一般小于其需要使用内存的总量。这样一个稳定的运行状态,我们可以称为working set: 被该程序频繁访问的内存页的集合。在windows上,你可以使用SetWorkingSetSize Win32 API来增加程序使用物理内存的数量。 -> non-paged pool        不可交换的内存。这主要指以non-paged的方式分配的内存,这些内存就像locked pages一样,是从来不会被交换出去的,用来存放一些由内核组件,driver访问的信息。 在Winsock应用开发过程中,以下的操作可能导致分配non-paged内存。 1) 调用系统一些系统的API,例如打开文件,create socket,等,都会导致从non-paged pool分配内存。 2) 一些driver可以显式地从该区域分配内存。 二) Winsock server上Locked Pages使用。         我们提到过,任何的overlapped IO操作,都会导致锁定内存页。这些内存页一旦被locked,就不会被交换出去。我们知道,windows操作系统对最大的可锁定内存页做了一个上限,如果超出这个上限,overlapped IO调用将会导致WSAENOBUFS错误。         考虑下面的情况,如果server在每个连接上会发出很多的overlapped receives操作,那么,随着连接数目的增多,很明显,被锁定的内存数量很有可能达到上限而导致WSAENOBUFS错误。在这种情况下,如果服务器预期会处理大数量的客户端连接,则需要服务器在每个连接上发出zero-byte buffer的overlapped接收请求(这种情况下,因为the size of buffer is zero,所以没有任何内存被锁定),一旦overlapped接收操作完成,server可以以non-blocking方式执行receive操作,以取得所有缓存在so_rcvbuf中的数据,直到返回WSAEWOULDBLOCK为止。         另外需要注意的是,windows在page的边界上对内存进行锁定,在x86平台上,它是4kb的整数倍。所以,假如你post了一个1 KB buffer,而系统真实锁定的是4 KB 的大小,为了避免这样的浪费,尽量用4kb的整数做overlapped  IO操作。 三) Winsock server上non-paged pool使用。         同Locked Pages限制一样,windows对non-paged pool也有一个最大的限制。并且,当你的应用出现这个问题的时候,超出它的最大限制数,情况要远比Locked Pages复杂。这种情况下,后果是不确定的,有可能你的Winsock调用返回WSAENOBUFS错误,也有可能,在系统中,一个和你的应用毫无关联的driver由于申请不到non-paged内存而致使system crash。而这样的灾难,是没法恢复的。         考虑一个具体的例子:我们假设在windows2000上,系统有1 GB内存。这样的配置下,windows大概会预留1/4的空间用作non-paged pool(同样,对于程序的开发人员,不应该对这个值进行任何的假设),即:256MB。这样的配置下,保守估计,我们的Winsock server能够处理到大概50,000连接,或者更多。(每个accepted socket大概消耗1.5kb,每个连接上post一个overlapped操作,分配一个IRP,大概需要500 byte, 总计:(1500+500)*50,000 = 100 Mb) 。        无论是对于Locked Pages,还是对于non-paged pool使用,一旦超出了上限,Winsock调用仅仅会返回一般的WSAENOBUFS 或者ERROR_INSUFFICIENT_RESOURCES错误。为了处理这些错误,你可以试试以下的方法: 1) 需要首先调用SetWorkingSetSize,增加应用的可支配资源数,看能否解决。 2)     确信你的应用没有做出太多的overlapped  IO操作。 3) 关闭一些连接数。 四) SOCKET的缓冲区设置问题。          Winsock在默认的情况下,每个socket都会与一个send和receive buffer相关联。你可以通过调用setsockopt来设置buffer的大小。         在缓冲区没有被关闭的情况下,我们看看overlapped send和revc是怎么工作的。         当上层的应用做出了send调用,而这时如果send buffer还有剩余的空间,那么数据将会从用户提交的buffer复制到send buffer中,然后调用返回成功。否则,假如这时send buffer已满,用户提交的buffer将会被锁定,并且调用返回WSA_IO_PENDING。当send buffer的数据被下层的tcp处理完成,winsock将直接处理用户提交的buffer里的数据,而不需要再复制。         同样,对于recv操作,如果数据已经被缓存在socket的receive buffer里,当发生recv调用的时候,数据将直接从socket的receive buffer复制到用户的buffer里,recv调用返回成功。否则,假如发生调用时receive buffer里没有数据,用户提交的buffer将会被锁定,recv调用返回WSA_IO_PENDING。当数据到达当前连接,将会被直接复制到用户提交的buffer里。         一个应用程序通过设定send buffer为0,把缓冲区关闭,然后发出一个阻塞send()调用。在这样的情况下,系统内核会把应用程序的缓冲区锁定,直到接收方确认收到了整个缓冲区后send()调用才返回。似乎这是一种判定你的数据是否已经为对方全部收到的简洁的方法,实际上却并非如此。想想看,即使远端tcp通知数据已经收到,其实也根本不代表数据已经成功送给客户端应用程序,比如对方可能发生资源不足的情况,导致afd.sys不能把数据拷贝给应用程序。另一个更要紧的问题是,在每个线程中每次只能进行一次发送调用,效率极其低下。         另外,希望通过关闭Winsock缓冲区,从而避免数据复制,达到优化性能的目的,也是不可取的。从上面,我们看到:只要应用保证适量的,足够的send, recv调用,这样的复制是完全可以避免的。         高性能的服务器应用程序可以关闭发送缓冲区,同时不会损失性能。不过,这样的应用程序必须十分小心,保证它总是发出多个重叠发送调用,而不是等待某个重叠发送结束了才发出下一个。如果应用程序是按一个发完再发下一个的顺序来操作,那浪费掉两次发送中间的空档时间,总之是要保证传输驱动程序在发送完一个缓冲区后,立刻可以转向另一个缓冲区。         如果关闭了recv buffer,在你的应用没有保证足够的recv操作前提下,任何进来数据,必须在TCP层进行缓存,最大缓存的数量将取决于tcp windows的大小(17Kb)。而最为严重的是这些缓存是从non-paged pool分配而来。如上所述,non-paged pool是非常珍贵,稀缺的内存。所以,从这个意义上来讲,关闭了recv buffer操作是不可取的。     这是2007年最后一篇帖子,最后祝大家新年快乐,过个好年!!!

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大四体育没过怎么办 大二体育挂了怎么办 大学体育刚刚及格怎么办 大学体育课没选怎么办 大专挂科拿不到毕业证怎么办 大学专业课挂科怎么办 专科重修没过怎么办 大学毕业证没领怎么办 大一数学挂科怎么办 大学体育课挂了怎么办 大一考试挂科怎么办 一年级孩子考试不及格怎么办 孩子一年级数学不及格怎么办 一年级孩子考试紧张怎么办 健身动作不标准怎么办 足球赛踢平了怎么办 踢球指甲淤血了怎么办 初中一年级成绩差怎么办 着火了怎么办小班教案 小孩爱玩游戏怎么办 幼儿上学哭闹老师怎么办 孩子不喜欢上幼儿园怎么办 幼儿喜欢脱鞋怎么办 幼儿在教室乱跑怎么办 转学学校不接收怎么办 留守儿童成绩差怎么办 感冒鼻孑堵咳嗽哮喘怎么办 二年级数学报怎么办 不敢翻前滚翻怎么办啊 大学全挂了怎么办 幼儿园热了怎么办教案 幼儿园小班热了怎么办教案 高考艺术生色弱怎么办 雾眉后出现白棱怎么办 lol皮肤重复了怎么办 怕篮球砸到怎么办 前滚翻向一侧偏怎么办 大腿肌肉比较发达怎么办 学计算机老了怎么办 新生儿头尖尖的怎么办 手抻筋了很疼怎么办