TcpListener的异步调用内存泄漏---最近测试结果,没有泄露
我后来加大了client的连接/断开的次数(500,1000),Server端的连接被释放了。
这说明:
1. 此代码是 可以正常工作的。
2.TcpListener/TcpListener的async的使用上,编译器生成的代码并没有在socket关闭的时候显式调用Disopose(),Dispose()在GC的时候被调用的,个人猜测可能是Pooling,也可能是生成的代码不够漂亮。
--------------------------------------------
最近想写个socket通信的小程序,我相信大凡用过async/await特性的人再也不会去写APM、EAP之类的代码,tcp层的异步通信网上也有很多例子,MSDN上的例子如下: https://msdn.microsoft.com/en-us/magazine/dn605876.aspx , 我参考这个例子写了个Demo,结果发现有内存泄漏,细想应该是某些地方用的不对了,如果有哪位大神看出来,请帮忙指正:
Server端代码:
我们可以看到Tcp上使用TcpListener,并且异步的实现实在NetworkStream上。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace AsyncTcpListenerServer
{
using System.IO;
class Program
{
static void Log(string msg)
{
Console.WriteLine($"Thread:{Thread.CurrentThread.ManagedThreadId} {msg}");
} static void Main(string[] args)
{
ProcessConnectClient();
Log("Listened success.");
Console.ReadLine();
} static async void ProcessConnectClient()
{
IPAddress ipAddress = IPAddress.Loopback;
TcpListener listener = new TcpListener(ipAddress, );
listener.Start(); Log("Begin start listen..."); while (true)
{
try
{
TcpClient client = await listener.AcceptTcpClientAsync().ConfigureAwait(false);
Log($"listened: {client.Client.RemoteEndPoint}");
ProcessReceiveData(client); }
catch (Exception ex)
{
Console.WriteLine("error:" + ex.ToString());
}
}
} static async void ProcessReceiveData(TcpClient client)
{
//client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
IPEndPoint endPoint = (IPEndPoint)client.Client.RemoteEndPoint;
string info = client.Client.RemoteEndPoint.ToString();
try
{
#region
//using (NetworkStream networkStream = client.GetStream())
//{
// byte[] buffer = new byte[client.ReceiveBufferSize];
// while (true)
// {
// int byteRead = await networkStream.ReadAsync(buffer, 0, client.ReceiveBufferSize).ConfigureAwait(false);
// if (byteRead <= 0)
// {
// break;
// }
// Log($" IP:{endPoint.Address} Port:{endPoint.Port} received {byteRead} bytes");
// }
//}
#endregion #region MyRegion
using (NetworkStream networkStream = client.GetStream())
using (MemoryStream memoryStream = new MemoryStream())
{
byte[] buffer = new byte[client.ReceiveBufferSize];
while (true)
{
int byteRead = await networkStream.ReadAsync(buffer, , client.ReceiveBufferSize).ConfigureAwait(false);
if (byteRead <= )
{
break;
}
await memoryStream.WriteAsync(buffer, , byteRead).ConfigureAwait(false);
byte[] bytes = memoryStream.ToArray();
memoryStream.Seek(, SeekOrigin.Begin); string str = Encoding.ASCII.GetString(bytes); Log($" IP:{endPoint.Address} Port:{endPoint.Port} {str}");
}
}
#endregion #region MyRegion
//using (NetworkStream networkStream = client.GetStream())
//using (StreamReader reader = new StreamReader(networkStream))
//{
// while (true)
// {
// string msg = await reader.ReadLineAsync().ConfigureAwait(false);
// if (msg == null)
// {
// break;
// } // Log($" IP:{endPoint.Address} Port:{endPoint.Port} {msg}");
// }
//}
#endregion }
catch (Exception ex)
{
Log(ex.ToString());
}
finally
{
Console.WriteLine($"client closed!");
client.Close();
}
}
}
}
Client端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace AsyncTcpClientClient
{
class Program
{
static void Main(string[] args)
{
Task t = Sending();
t.Wait();
Console.WriteLine("OK client");
} static async Task Sending()
{
TcpClient client = new TcpClient();
try
{
await client.ConnectAsync(IPAddress.Loopback, );
using (NetworkStream stream = client.GetStream())
{
int i = ;
while (stream.CanWrite)
{
i++;
if (i>)
{
break;
}
string msg = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
byte[] ba = Encoding.Default.GetBytes(msg);
await stream.WriteAsync(ba, , ba.Length);
//System.IO.StreamWriter writer = new System.IO.StreamWriter(stream);
//writer.AutoFlush = true;
//await writer.WriteLineAsync(msg); Console.WriteLine($"Send...{msg}");
Thread.Sleep();
}
} }
catch (Exception ex)
{
Console.WriteLine(ex); }
finally
{
if (client.Connected)
{
client.Close();
}
}
}
}
}
写法是特别简单,但是。。。
开启Server端后,运行Client3次端,Server端的显示:
可以看到通信成功,此时抓取Dump,分析结果如下:
Microsoft (R) Windows Debugger Version 10.0.10240.9 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [C:\Users\StevenChen\AppData\Local\Temp\AsyncTcpListenerServer (8).DMP]
User Mini Dump File with Full Memory: Only application data is available
WARNING: Minidump contains unknown stream type 0x15
WARNING: Minidump contains unknown stream type 0x16
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path. *
* Use .symfix to have the debugger choose a symbol path. *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is:
Windows 10 Version 10240 MP (8 procs) Free x64
Product: WinNt, suite: SingleUserTS
Built by: 10.0.10240.16384 (th1.150709-1700)
Machine Name:
Debug session time: Tue Dec 15 17:29:05.000 2015 (UTC + 8:00)
System Uptime: 1 days 8:03:25.088
Process Uptime: 0 days 0:00:49.000
.....................................
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
************* Symbol Loading Error Summary **************
Module name Error
ntdll The system cannot find the file specified
You can troubleshoot most symbol related issues by turning on symbol loading diagnostics (!sym noisy) and repeating the command that caused symbols to be loaded.
You should also verify that your symbol search path (.sympath) is correct.
*** ERROR: Symbol file could not be found. Defaulted to export symbols for KERNELBASE.dll -
ntdll!ZwReadFile+0xa:
00007ff9`313135da c3 ret
0:000> .symfix d:\symbols
0:000> .loadby sos clr
0:000> !fq
No .natvis files found at C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers.
c0000005 Exception in C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.fq debugger extension.
PC: 00007ff8`e01b2085 VA: 00000000`00000000 R/W: 0 Parameter: 00000000`00000000
0:000> !fq
SyncBlocks to be cleaned up: 0
Free-Threaded Interfaces to be released: 0
MTA Interfaces to be released: 0
STA Interfaces to be released: 0
----------------------------------
generation 0 has 123 finalizable objects (0000001d743340e0->0000001d743344b8)
generation 1 has 0 finalizable objects (0000001d743340e0->0000001d743340e0)
generation 2 has 0 finalizable objects (0000001d743340e0->0000001d743340e0)
Ready for finalization 0 objects (0000001d743344b8->0000001d743344b8)
Statistics for all finalizable objects (including all objects ready for finalization):
MT Count TotalSize Class Name
00007ff91a6f2ec0 1 32 Microsoft.Win32.SafeHandles.SafeFileMappingHandle
00007ff91a6f2e30 1 32 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle
00007ff91a6eab30 1 32 Microsoft.Win32.SafeHandles.SafeWaitHandle
00007ff91a6d1028 1 32 Microsoft.Win32.SafeHandles.SafePEFileHandle
00007ff91a6c1190 1 32 System.Threading.Gen2GcCallback
00007ff91a685878 1 40 System.Threading.RegisteredWaitHandleSafe
00007ff9134adbe8 3 120 System.Net.Sockets.TcpClient
00007ff91a6f0fe8 4 128 Microsoft.Win32.SafeHandles.SafeFileHandle
00007ff91a6d0fc0 2 128 System.Threading.ReaderWriterLock
00007ff91a6d3ff0 2 176 System.Diagnostics.Tracing.EventSource+OverideEventProvider
00007ff91a6ac5e8 1 184 System.Threading.PinnableBufferCacheEventSource
00007ff91a690ab8 1 184 System.Threading.Tasks.TplEtwProvider
00007ff9134ddac8 6 192 System.Net.SafeNativeOverlapped
00007ff9134d5790 3 192 System.Net.Sockets.NetworkStream
00007ff91a6de1e8 2 208 System.IO.FileStream
00007ff9134dda38 6 240 System.Net.SafeCloseSocket
00007ff9134dd820 8 256 System.Net.SafeCloseSocket+InnerSafeCloseSocket
00007ff91a6eee60 3 288 System.Threading.Thread
00007ff91a6d00f8 9 288 Microsoft.Win32.SafeHandles.SafeRegistryHandle
00007ff9134d6aa8 6 288 System.Net.Sockets.OverlappedCache
00007ff91a6e9a20 14 336 System.WeakReference
00007ff9134b60f0 3 528 System.Net.Sockets.AcceptOverlappedAsyncResult
00007ff91a6d3148 21 672 Microsoft.Win32.SafeHandles.SafeAccessTokenHandle
00007ff9134dc7c0 5 680 System.Net.Sockets.Socket
00007ff9134d7368 18 3312 System.Net.Sockets.OverlappedAsyncResult
Total 123 objects
0:000> !dumpheap -mt 00007ff9134dc7c0
Address MT Size
0000001d00034540 00007ff9134dc7c0 136
0000001d00040110 00007ff9134dc7c0 136
0000001d00052de0 00007ff9134dc7c0 136
0000001d000680d8 00007ff9134dc7c0 136
0000001d0007a780 00007ff9134dc7c0 136
Statistics:
MT Count TotalSize Class Name
00007ff9134dc7c0 5 680 System.Net.Sockets.Socket
Total 5 objects
0:000> !gcroot 0000001d00034540
HandleTable:
0000001d71741350 (strong handle)
-> 0000001d0003be08 System.Threading._ThreadPoolWaitOrTimerCallback
-> 0000001d00034540 System.Net.Sockets.Socket
0000001d71741be0 (async pinned handle)
-> 0000001d00052860 System.Threading.OverlappedData
-> 0000001d0007a6d0 System.Net.Sockets.AcceptOverlappedAsyncResult
-> 0000001d00034540 System.Net.Sockets.Socket
Found 2 unique roots (run '!GCRoot -all' to see all roots).
0:000> !gcroot 0000001d00040110
Finalizer Queue:
0000001d00040110
-> 0000001d00040110 System.Net.Sockets.Socket
0000001d00040328
-> 0000001d00040328 System.Net.Sockets.TcpClient
-> 0000001d00040110 System.Net.Sockets.Socket
0000001d00040c88
-> 0000001d00040c88 System.Net.Sockets.NetworkStream
-> 0000001d00040110 System.Net.Sockets.Socket
0000001d00050f20
-> 0000001d00050f20 System.Net.Sockets.OverlappedAsyncResult
-> 0000001d00040110 System.Net.Sockets.Socket
0000001d00054ba0
-> 0000001d00054ba0 System.Net.Sockets.OverlappedAsyncResult
-> 0000001d00040110 System.Net.Sockets.Socket
0000001d00054ff8
-> 0000001d00054ff8 System.Net.Sockets.OverlappedAsyncResult
-> 0000001d00040110 System.Net.Sockets.Socket
0000001d00055450
-> 0000001d00055450 System.Net.Sockets.OverlappedAsyncResult
-> 0000001d00040110 System.Net.Sockets.Socket
0000001d000558a8
-> 0000001d000558a8 System.Net.Sockets.OverlappedAsyncResult
-> 0000001d00040110 System.Net.Sockets.Socket
0000001d00055d00
-> 0000001d00055d00 System.Net.Sockets.OverlappedAsyncResult
-> 0000001d00040110 System.Net.Sockets.Socket
Warning: These roots are from finalizable objects that are not yet ready for finalization.
This is to handle the case where objects re-register themselves for finalization.
These roots may be false positives.
Found 9 unique roots (run '!GCRoot -all' to see all roots).
0:000> !dumpheap -mt 00007ff9134d7368
Address MT Size
0000001d00050f20 00007ff9134d7368 184
0000001d00054ba0 00007ff9134d7368 184
0000001d00054ff8 00007ff9134d7368 184
0000001d00055450 00007ff9134d7368 184
0000001d000558a8 00007ff9134d7368 184
0000001d00055d00 00007ff9134d7368 184
0000001d00067c60 00007ff9134d7368 184
0000001d00068a00 00007ff9134d7368 184
0000001d00068e58 00007ff9134d7368 184
0000001d000692b0 00007ff9134d7368 184
0000001d00069708 00007ff9134d7368 184
0000001d00069b60 00007ff9134d7368 184
0000001d0007a308 00007ff9134d7368 184
0000001d0007aea0 00007ff9134d7368 184
0000001d0007b2f8 00007ff9134d7368 184
0000001d0007b750 00007ff9134d7368 184
0000001d0007bba8 00007ff9134d7368 184
0000001d0007c000 00007ff9134d7368 184
Statistics:
MT Count TotalSize Class Name
00007ff9134d7368 18 3312 System.Net.Sockets.OverlappedAsyncResult
Total 18 objects
0:000> !gcroot 0000001d00054ff8
Finalizer Queue:
0000001d00054ff8
-> 0000001d00054ff8 System.Net.Sockets.OverlappedAsyncResult
Warning: These roots are from finalizable objects that are not yet ready for finalization.
This is to handle the case where objects re-register themselves for finalization.
These roots may be false positives.
Found 1 unique roots (run '!GCRoot -all' to see all roots).
我们能够比较明显的看出有些对象没有释放,这些对象的root都指向System.Net.Sockets.OverlappedAsyncResult,但是很奇怪System.Net.Sockets.OverlappedAsyncResult本身也是一个根。
TcpListener的异步调用内存泄漏---最近测试结果,没有泄露的更多相关文章
- Android应用内存泄漏的定位、分析与解决策略
什么是内存泄漏 对于不同的语言平台来说,进行标记回收内存的算法是不一样的,像 Android(Java)则采用 GC-Root 的标记回收算法.下面这张图就展示了 Android 内存的回收管理策略( ...
- 一个跨平台的 C++ 内存泄漏检测器
2004 年 3 月 01 日 内存泄漏对于C/C++程序员来说也可以算作是个永恒的话题了吧.在Windows下,MFC的一个很有用的功能就是能在程序运行结束时报告是否发生了内存泄漏.在Linux下, ...
- Android内存泄漏的检测流程、捕捉以及分析
https://blog.csdn.net/qq_20280683/article/details/77964208 Android内存泄漏的检测流程.捕捉以及分析 简述: 一个APP的性能,重度关乎 ...
- Web 2.0 浏览器端可靠性测试第2部分(如何发现和分析 Web 2.0 浏览器端的内存泄漏)
介绍浏览器端的可靠性测试 在上一编文章中我们介绍了浏览器端可靠性测试的概念.测试方法.以及常用的测试和分析工具.我们知道,浏览器端可靠性测试,就是以浏览器为测试平台,通过模拟用户在真实场景下的页面操作 ...
- Google单元测试框架gtest之官方sample笔记4--事件监控之内存泄漏测试
sample 10 使用event listener监控Water类的创建和销毁.在Water类中,有一个静态变量allocated,创建一次值加一,销毁一次值减一.为了实现这个功能,重载了new和d ...
- 走进异步世界:EnyimMemcached异步化改造引起的内存泄漏
6月30日我们发布了异步化改造后的博客程序之后,出现了高内存.高CPU.高线程数的不理想情况. 经过一周的追查,终于水落日出——引起不理想情况的根源是我们修改过的EnyimMemcached代码存在内 ...
- Qt 内存泄漏测试
在说Qt的内存测试之前,首先需要说明和肯定的一点是:Qt是绝对没有内存泄漏的,我们必须相信这一点. 接下来,说明一下基于Linux的Qt内存测试工具及其用法和说明: 一.内存测试工具Valgrind ...
- WEB页面异步调用场景测试
在我们测试异步调用前,我们首先弄清楚异步调用到底是什么? 异步调用的定义:一个可以无需等待被调用函数的返回值就让操作继续进行的方法, 举一个形象的例子就是:领导给A分配了一个任务, 然后领导就干其他事 ...
- AFNetworking 3.0中调用[AFHTTPSessionManager manager]方法导致内存泄漏的解决办法
在使用AFNetworking3.0框架,使用Instruments检查Leaks时,检测到1000多个内存泄漏的地方,定位到 [AFHTTPSessionManager manager] 语句中,几 ...
随机推荐
- 新春测 kinect motor
大年30,祝所有开发伙伴新春快乐. 天天FQ, 叹国内学习成本太高 看到一篇台湾 kinect 电机控制, 赞 using Microsoft.Kinect; using System; using ...
- APACHE 在windows下的配置
目前apache在windows下只支持到2.2 所以php必须下载相应的线程安全的 然后打开apache的配置页面 listen directory 和 load_module修改 httpd -k ...
- C++中的const和指针组合
在C++里,const修饰指针有以下三种情况 (1)指针常量:即指向常量的指针 const int *p或者int const *p const在*前,,可以这样理解它的功能,因为const在*前, ...
- 用computed返回this.$store.state.count,store更改了,但是computed没有调用
今天出现了这个问题,store更新了,你computed为啥不调用呢??? 另一个.vue更新了state,这个的computed就监听不到了么? 是用这种格式更新的this.$store.commi ...
- jQuery 绑定事件
$('input').bind('click mouseover', fn); $('input').bind({ mouseover: fn(){}, mouseover:fn(){} }); 删除 ...
- Swift 07.关键字
每一种语言都有相应的关键词,每个关键词都有他独特的作用,来看看swfit中的关键词: 关键词: 用来声明的: class, deinit, enum, extension, func, import, ...
- 转:solr6.0配置中文分词器IK Analyzer
solr6.0中进行中文分词器IK Analyzer的配置和solr低版本中最大不同点在于IK Analyzer中jar包的引用.一般的IK分词jar包都是不能用的,因为IK分词中传统的jar不支持s ...
- Putty 配图
- 书旗小说app点评
书旗小说这个手机软件用了好久了,大一的时候就开始用,业余无聊时间可以看一看网络小说打发一下时间. 书旗免费小说是一款内容以免费小说书旗网为基础的在线阅读器,除了拥有传统阅读器的书籍同步阅读.全自动书签 ...
- Matrix(单点移动,多点缩放)
package cn.iris.matrixapi; import android.app.Activity; import android.graphics.Matrix; import andro ...