您在使用.net程序时使用了哪些分析器,您会特别推荐哪些?
我有一个'服务'(owin/webapi + odp.net托管),在x64机器上运行'server gc mode'.执行测试套件后,内存使用量约为2Gb.我'在那台机器上产生了'内存压力'(另一个消耗了所有可用内存的程序).我原以为Windows会强制.net释放一些内存.但事实并非如此.这是windbg的输出:
0:018> !dumpheap -stat
Statistics:
MT Count TotalSize Class Name
00007ffd10445b90 1 24 System.Collections.Generic.GenericEqualityComparer`1[[System.UInt64, mscorlib]]
...
00007ffd0f904918 100864 11616976 System.Object[]
0000005b19face20 84 1810674044 Free
Total 720544 objects
Fragmented blocks larger than 0.5 MB:
Addr Size Followed by
0000005b1c3c8800 425.6MB 0000005b36d56c50 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005c1c3fcf00 28.2MB 0000005c1e02be58 System.Reflection.Emit.MethodBuilder
0000005c1e02e5b0 268.0MB 0000005c2ec313d8 System.Threading.OverlappedData
0000005c2ec31678 142.3MB 0000005c37a830a0 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005d1c541aa0 404.8MB 0000005d35a1a958 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005d35a1e5a8 3.8MB 0000005d35df0c40 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005e1cfe7128 444.1MB 0000005e38c0c3f0 System.Byte[]
0000005e38c8cfb8 4.5MB 0000005e39110988 …Run Code Online (Sandbox Code Playgroud) 我曾经在.NET中编写了一个Crawler.为了提高其可伸缩性,我尝试利用.NET的异步API.
System.Net.HttpWebRequest具有异步API BeginGetResponse/EndGetResponse.但是,这对API只是为了获取HTTP响应头和Stream实例,我们可以从中提取HTTP响应内容.所以,我的策略是使用BeginGetResponse/EndGetResponse来异步获取响应Stream,然后使用BeginRead/EndRead从响应Stream实例异步获取字节.
在Crawler进行压力测试之前,一切看起来都很完美.在压力测试下,Crawler遭受高内存使用.我用WinDbg + SoS检查了内存,并说明System.Threading.OverlappedData实例有很多字节数组.经过一些互联网搜索后,我从微软发现了这个KB http://support.microsoft.com/kb/947862.
根据KB,异步I/O的数量应该具有"上限",但它不会告诉"建议的"绑定值.所以,在我看来,这个KB没有任何帮助.这显然是一个.NET错误.最后,我不得不放弃从响应Stream中异步提取字节的想法,而只是以同步方式进行.
允许带有点网络套接字的异步IO的.NET库(Socket.BeginSend/Socket.BeginReceive/NetworkStream.BeginRead/NetworkStream.BeginWrite)必须具有其异步IO的未完成缓冲区(发送或接收)数量的上限.
网络应用程序应该具有其发布的未完成异步IO 数量的上限 .
编辑:添加一些问号.
任何人都有在Socket和NetworkStream上进行异步I/O的经验吗?一般来说,生产中的爬虫是否通过同步或异步的互联网进行I/O操作?
在下面的代码中,似乎client.Connect.Receive永久地固定"byte []结果",导致永远不会释放内存(因为它总是被固定).我正在寻找一种方法来告诉C#,在使用它之后不再需要固定它.OnReceive,但我找不到内置函数或关键字来执行此操作.
有谁知道如何让C#取消固定byte []数组?(这是我的C#应用程序中的内存泄漏源之一)
this.m_TcpListener = new TcpListener(this.p_TcpEndPoint.Port);
this.m_TcpThread = new Thread(delegate()
{
try
{
this.m_TcpListener.Start();
while (this.p_Running)
{
TcpClient client = this.m_TcpListener.AcceptTcpClient();
new Thread(() =>
{
try
{
// Read the length header.
byte[] lenbytes = new byte[4];
int lbytesread = client.Client.Receive(lenbytes, 0, 4, SocketFlags.None);
if (lbytesread != 4) return; // drop this packet :(
int length = System.BitConverter.ToInt32(lenbytes, 0);
int r = 0;
// Read the actual data.
byte[] result = new byte[length];
while (r < length)
{ …Run Code Online (Sandbox Code Playgroud) .net ×3
c# ×3
memory-leaks ×1
pinning ×1
profiler ×1
profiling ×1
sockets ×1
stream ×1
web-crawler ×1