【发布时间】:2017-11-30 15:09:59
【问题描述】:
我正在尝试找出我的 .net 核心应用程序与 protobuf 序列化问题的原因,所以我编写了一个测试应用程序并且......有些奇怪。如果我使用 Task 会有内存泄漏,如果我使用 Thread 则没有内存泄漏。
任务示例:
internal class Program
{
private static void Main(string[] args)
{
var data = new Person
{
Id = 1,
Name = new string('q', 10000),
Address = new Address
{
Line1 = new string('w', 10000),
Line2 = new string('e', 10000)
}
};
//for (var i = 0; i < 100; i++)
//{
// var thread = new Thread(() =>
// {
// while (true)
// try
// {
// var b = ProtoSerialize(data);
// Person serializedPerson;
// using (Stream stream2 = new MemoryStream(b))
// {
// serializedPerson = Serializer.Deserialize<Person>(stream2);
// }
// }
// catch (Exception e)
// {
// Console.WriteLine(e);
// }
// });
// thread.Start();
//}
for (var i = 0; i < 100; i++)
{
new Task(() =>
{
while (true)
{
var b = ProtoSerialize(data);
Person serializedPerson;
using (Stream stream2 = new MemoryStream(b))
{
serializedPerson = Serializer.Deserialize<Person>(stream2);
}
}
}).Start();
}
Console.ReadLine();
}
public static byte[] ProtoSerialize<T>(T record) where T : class
{
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, record);
return stream.ToArray();
}
}
}
[ProtoContract]
public class Person
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3)]
public Address Address { get; set; }
}
[ProtoContract]
public class Address
{
[ProtoMember(1)]
public string Line1 { get; set; }
[ProtoMember(2)]
public string Line2 { get; set; }
}
所以如果我使用线程(注释代码)
for (var i = 0; i < 100; i++)
{
var thread = new Thread(() =>
{
while (true)
try
{
var b = ProtoSerialize(data);
Person serializedPerson;
using (Stream stream2 = new MemoryStream(b))
{
serializedPerson = Serializer.Deserialize<Person>(stream2);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
});
thread.Start();
}
所以问题是:
我做错了吗?
为什么会这样?
怎么做?
附言
protobuf-net 是 2.3.2
.net 核心 2.0
UPD1:在主线程中调用 GC.Collect 没有任何改变(仍然存在内存泄漏)
【问题讨论】:
-
打开快照比较,打开“新”对象,看看这些对象是什么以及它们为什么保存在内存中。使用内存分析器功能。
-
注意:昨天发布了一个新版本,它解决了一个非常具体的内存场景 - 不确定这是否相关,但您可能想尝试一下
-
我遇到了完全相同的问题,正在处理大对象并使用 dotmemory 发现是在 Serializer 类上
标签: multithreading memory-leaks asp.net-core protocol-buffers protobuf-net