socket内存问题--细节的优化


这两天做socket通信,服务器端和客户端都做好之后进行了一些简单的压力测试。发现服务器端的内存不断上升,1000个并发,12128B的包,30秒进程突破100M

像我这种对GC处理,内存释放一窍不通的“处”,只好找资料了。


资料:.net 中异步SOCKET发送数据时碰到的内存问题


 

根据资料显示,可能是new了太多的SocketAsyncEventArgs或者 new 了太多的byte[]造成的,我想了想我的代码里好像循环new了很多的SocketAsyncEventArgs和byte[],主代码暂时不想改,就先按照资料的例子来做个测试。

 

例子1

          

            Console.WriteLine("Press any key to start.");
            Console.ReadKey();
 
            for (int i = 0; i < 1000000; ++i)
            {
                Console.WriteLine(i);
                for (int j = 0; j < 10000; ++j)
                {
                    SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                }
                System.Threading.Thread.Sleep(100);
            }
            Console.ReadLine();

 

   测试结果,发现内存跳跃很厉害,8M-12.5M之间。

例子2

 

	    Console.WriteLine("Press any key to start.");
            Console.ReadKey();
 
            for (int i = 0; i < 1000000; ++i)
            {
                Console.WriteLine(i);
                for (int j = 0; j < 10000; ++j)
                {
                    SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                }
                GC.Collect(2);   //这句话还不知道啥意思
                System.Threading.Thread.Sleep(100);
            }
            Console.ReadLine();

 

 测试结果:这次加上GC回收,程序变的稳定了起来。8.5M左右,基本不跳动。

 

后来我想,为什么要new这么多次呢?为什么我不能new一个,然后其他都去复制过来?

 

例子3

   

   public  SocketAsyncEventArgs _s =new SocketAsyncEventArgs();
   public void Test1()
        {
            Console.WriteLine("Press any key to start.");
            Console.ReadKey();
 
            for (int i = 0; i < 1000000; ++i)
            {
                Console.WriteLine(i);
                for (int j = 0; j < 10000; ++j)
                {
                    SocketAsyncEventArgs e = _s;
                }
                GC.Collect(2);
                System.Threading.Thread.Sleep(100);
            }
            Console.ReadLine();
        }

测试结果:内存始终维持在1.7M,非常稳定。

 

其实例子3我还是比较担心的,怕有什么意外发生,或者违反什么规则希望有大牛看到能够及时点评

 

 

然后byte[]我也进行了一次测试。

 

 

        public byte[] _b = new byte[1024 * 1024 * 2];
 
        public void Test2()
        {
            Console.WriteLine("Press any key to start.");
            Console.ReadKey();
 
            for (int i = 0; i < 1000000; ++i)
            {
                Console.WriteLine(i);
                for (int j = 0; j < 10000; ++j)
                {
                    byte[] b = _b;
                }
                //GC.Collect(2);
                System.Threading.Thread.Sleep(10);
            }
            Console.ReadLine();
        }

 

最终代码如下:

测试结果,每次有new一次的话,不仅程序运行很慢,而且内存在10M左右。

提前new一次的话,程序运行大概是原来的100倍以上,内存仅占1.9M

 

不信邪的同学可以测试一下,很可怕的。 :)

 

最终经过多次细节上的优化,现在我的server端已经稳定下来了。对此方面比较专业的大牛,请指导一下

 

由于这是工作代码,所以不提供源码,抱歉!

 

压力测试工具:强大的TcpServer压力测试工具及源码(附突破连接限制的方法和工具)

 

你可能感兴趣的:(.Net)