c# - 发现内存泄漏
问题描述
我对以下代码有疑问。我在 GetDB 函数中创建了一个内存流,并在using块中使用了返回值。出于某种未知原因,如果我转储我的对象,我发现 MemoryStream 仍然在 Main 方法的末尾。这导致我大量泄漏。知道如何清理这个缓冲区吗?
我实际上已经检查过在 MemoryStream 上调用了 Dispose 方法,但该对象似乎仍然存在,我已使用 Visual Studio 2017 的诊断工具来完成此任务。
class Program
{
static void Main(string[] args)
{
List<CsvProduct> products;
using (var s = GetDb())
{
products = Utf8Json.JsonSerializer.Deserialize<List<CsvProduct>>(s).ToList();
}
}
public static Stream GetDb()
{
var filepath = Path.Combine("c:/users/tom/Downloads", "productdb.zip");
using (var archive = ZipFile.OpenRead(filepath))
{
var data = archive.Entries.Single(e => e.FullName == "productdb.json");
using (var s = data.Open())
{
var ms = new MemoryStream();
s.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
return (Stream)ms;
}
}
}
}
解决方案
出于某种未知原因,如果我转储我的对象,我发现 MemoryStream 仍然在 Main 方法的末尾。
这并不是特别不正常。GC 是单独发生的。
这导致我大量泄漏。
这不是泄漏,它只是内存使用。
知道如何清理这个缓冲区吗?
我可能只是不使用 aMemoryStream
,而是返回包装实时解压缩流的内容(来自s = data.Open()
)。但是,这里的问题是您不能只返回s
-archive
离开该方法时仍然会被处理掉。因此,如果我需要解决这个问题,我会创建一个自定义Stream
来包装内部流并在处理时处理第二个对象,即
class MyStream : Stream {
private readonly Stream _source;
private readonly IDisposable _parent;
public MyStream(Stream, IDisposable) {...assign...}
// not shown: Implement all Stream methods via `_source` proxy
public override void Dispose()
{
_source.Dispose();
_parent.Dispose();
}
}
然后有:
public static Stream GetDb()
{
var filepath = Path.Combine("c:/users/tom/Downloads", "productdb.zip");
var archive = ZipFile.OpenRead(filepath);
var data = archive.Entries.Single(e => e.FullName == "productdb.json");
var s = data.Open();
return new MyStream(s, archive);
}
(可以稍微改进以确保archive
在我们成功返回之前发生异常时处理)
推荐阅读
- html - 如何实现水平和垂直居中的多个图像之间的固定宽度间距
- android - 在我的 Rooted LG Stylo 3 plus 上可以为 Android 7 中的所有应用程序解锁外部 SD 卡写入
- angular - Angular 4 应用程序,此请求的授权已被拒绝
- dart - Flutter - How do I run a method after the Slider interaction has ended?
- python - 如何在 Django 中扩展管理视图?
- javascript - 无法从 componentDidMount 获取 ref
- django - Django 网址不匹配?
- java - 将 SpringRunner 与 PowermockRunner 一起使用时出现异常
- java - RasberryPi 上的 Java jlayer
- .htaccess - 将整个网站从 http 重定向到 https,除了一页