Socket accept正在windows上消耗内存而未释放
我用C编写了一个非常小的函数,打开一个套接字,接受连接并立即关闭它们 问题是,每个连接都会占用一些内存,而不会在任何时候将其释放到操作系统。我用大约300K个请求运行了ab(apachebenchmark),进程内存在不断增长(最后是几百兆字节) 我知道进程并不总是将其空闲内存返回操作系统。但一旦超过几兆字节,我认为它应该返回内存,还是我错了 这只发生在Windows上。在Linux上,我的内存使用率一直接近进程启动使用率 使用GCC 4.8.2编译。在Windows Server 2008 R2和Windows 8.1上测试Socket accept正在windows上消耗内存而未释放,c,windows,sockets,gcc,memory-management,C,Windows,Sockets,Gcc,Memory Management,我用C编写了一个非常小的函数,打开一个套接字,接受连接并立即关闭它们 问题是,每个连接都会占用一些内存,而不会在任何时候将其释放到操作系统。我用大约300K个请求运行了ab(apachebenchmark),进程内存在不断增长(最后是几百兆字节) 我知道进程并不总是将其空闲内存返回操作系统。但一旦超过几兆字节,我认为它应该返回内存,还是我错了 这只发生在Windows上。在Linux上,我的内存使用率一直接近进程启动使用率 使用GCC 4.8.2编译。在Windows Server 2008 R
void http_server_start(void) {
int rc;
struct sockaddr_in cfg;
#ifdef _WIN32
WORD ver;
WSADATA data;
ver=MAKEWORD(2,2);
rc=WSAStartup(ver, &data);
if(rc != 0){
printf("Error: Unable to initialize WSA (%d)", rc);
}
#endif
memset(&cfg, 0, sizeof(cfg));
cfg.sin_family = AF_INET;
cfg.sin_addr.s_addr = htonl(INADDR_ANY);
cfg.sin_port = htons(PORT);
server = socket(AF_INET, SOCK_STREAM, 6);
int reuseaddr=1;
if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof(reuseaddr)) == -1){
rc=GetLastErrorEx();
printf("Error: Unable to set SO_REUSEADDR (%d)\n", rc);
} else if (bind(server, (struct sockaddr *)&cfg, sizeof(cfg)) < 0 ) {
rc=GetLastErrorEx();
printf("Error: Unable to bind socket (%d)\n", rc);
close(server);
} else if (listen(server, QUEUE_SIZE) < 0) {
rc=GetLastErrorEx();
printf("Error: Unable to listen (%d)\n", rc);
close(server);
} else {
printf("Listening on %s:%d\n", inet_ntoa(cfg.sin_addr), ntohs(cfg.sin_port));
int client;
struct sockaddr_in addr;
int addrlen=sizeof(addr);
do {
client=accept(server, (struct sockaddr*)&addr, &addrlen);
if(client != -1){
shutdown(client, SHUT_RDWR);
close(client);
}
} while(1);
}
}
void http\u服务器\u启动(void){
int rc;
cfg中的结构sockaddr_;
#ifdef_WIN32
单词ver;
WSADATA数据;
ver=生成词(2,2);
rc=WSAStartup(版本和数据);
如果(rc!=0){
printf(“错误:无法初始化WSA(%d)”,rc);
}
#恩迪夫
memset(&cfg,0,sizeof(cfg));
cfg.sin_family=AF_INET;
cfg.sin_addr.s_addr=htonl(INADDR_ANY);
cfg.sin_port=htons(port);
服务器=套接字(AF_INET,SOCK_STREAM,6);
int=1;
if(setsockopt(服务器,SOL_套接字,SO_REUSEADDR,(char*)和REUSEADDR,sizeof(REUSEADDR))=-1){
rc=GetLastErrorEx();
printf(“错误:无法设置SO\u REUSEADDR(%d)\n)”,rc);
}else if(bind(server,(struct sockaddr*)&cfg,sizeof(cfg))<0){
rc=GetLastErrorEx();
printf(“错误:无法绑定套接字(%d)\n”,rc);
关闭(服务器);
}else if(侦听(服务器、队列大小)<0){
rc=GetLastErrorEx();
printf(“错误:无法侦听(%d)\n”,rc);
关闭(服务器);
}否则{
printf(“侦听%s:%d\n”、inet_ntoa(cfg.sin_addr)、ntohs(cfg.sin_端口));
int客户端;
地址中的结构sockaddr\u;
int addrlen=sizeof(addr);
做{
client=accept(服务器,(结构sockaddr*)&addr,&addrlen);
如果(客户端!=-1){
关闭(客户端,关闭\RDWR);
关闭(客户);
}
}而(1),;
}
}
要关闭套接字,请使用shutdown()和close()。 实际上,shutdown()强制终止连接,即使存在 指同一插座的多个描述符, shutdown()只允许在一个方向上关闭,close()不允许 影响连接状态,直到最后一个描述符 关闭 试用
int closesocket(Socket S);
应用程序每次成功调用socket时都应该有一个对closesocket()的匹配调用,以将任何套接字资源返回到系统。在Windows上,winsock使用
closesocket
来正确关闭和清理套接字。如果在Windows上使用closesocket
而不是close
,会发生什么,这是一个快速的。这就解决了问题,你介意把它作为答案贴出来让我接受吗?:)