Skip to content

Instantly share code, notes, and snippets.

@BrandonLWhite
Created April 11, 2014 23:26
Show Gist options
  • Save BrandonLWhite/10509361 to your computer and use it in GitHub Desktop.
Save BrandonLWhite/10509361 to your computer and use it in GitHub Desktop.
Mono memory leak using Socket BeginRead
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Net.Sockets;
using System.Net;
namespace FromAsyncLeakTest
{
/// <summary>
/// Use export MONO_GC_PARAMS=max-heap-size=16M to fill the heap to it's limit faster.
/// </summary>
class Program
{
public static List<byte[]> memoryPressure;
static void Main(string[] args)
{
// SGEN: Use 8192 byte chunks to create LOS objects.
// Adjust the number of blocks as you see fit.
memoryPressure = Enumerable.Range(0, 550).Select(i => new byte[8192]).ToList();
StartRawAsyncSocketReceive();
ClientTestLoop(8085);
}
static void StartRawAsyncSocketReceive()
{
var tcpServer = new TcpListener(IPAddress.Loopback, 8085);
tcpServer.Start();
BeginAcceptTcpClient(tcpServer);
}
static void BeginAcceptTcpClient(TcpListener tcpServer)
{
Task.Factory.FromAsync<TcpClient>(tcpServer.BeginAcceptTcpClient, tcpServer.EndAcceptTcpClient, null)
.ContinueWith(task =>
{
BeginAcceptTcpClient(tcpServer);
BeginTcpClientRead(task.Result.GetStream(), new byte[8192]);
});
}
static void BeginTcpClientRead(NetworkStream stream, byte[] buffer)
{
stream.BeginRead(buffer, 0, buffer.Length, (ar) => OnDataAvailable(ar, stream, buffer), null);
}
static void OnDataAvailable(IAsyncResult ar, NetworkStream stream, byte[] buffer)
{
int iBytes = stream.EndRead(ar);
Console.Write("{0}, ", iBytes);
BeginTcpClientRead(stream, buffer);
}
public static void ClientTestLoop(int iPort)
{
try
{
var tcpClient = new TcpClient("localhost", iPort);
var tcpStream = tcpClient.GetStream();
string sBuffer = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec in iaculis augue.";
byte[] content = Encoding.UTF8.GetBytes(sBuffer);
while (true)
{
tcpStream.Write(content, 0, content.Length);
// Throttle back just to demonstrate that the server will still leak and crash.
// (Take this out to see it run out of memory faster)
//
Thread.Sleep(2);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment