查找内存泄漏

我有以下代码的问题。我在 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;

            }

        }

    }

}


一只名叫tom的猫
浏览 167回答 1
1回答

月关宝盒

出于某种未知原因,如果我转储对象,我会看到 MemoryStream 仍在 Main 方法的末尾。这并不是特别不正常;GC 单独发生。这导致我大量泄漏。这不是泄漏,这只是内存使用情况。知道如何清理这个缓冲区吗?我可能只是不使用MemoryStream,而是返回包装实时解压缩流(来自s = data.Open())的东西。但是,这里的问题是您不能直接返回s——因为archive在离开方法时仍然会被处理。因此,如果我需要解决这个问题,我将创建一个Stream包装内部流的自定义,并在处理时处理第二个对象,即class MyStream : Stream {&nbsp; &nbsp; private readonly Stream _source;&nbsp; &nbsp; private readonly IDisposable _parent;&nbsp; &nbsp; public MyStream(Stream, IDisposable) {...assign...}&nbsp; &nbsp; // not shown: Implement all Stream methods via `_source` proxy&nbsp; &nbsp; public override void Dispose()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _source.Dispose();&nbsp; &nbsp; &nbsp; &nbsp; _parent.Dispose();&nbsp; &nbsp; }}然后有:public static Stream GetDb(){&nbsp; &nbsp; var filepath = Path.Combine("c:/users/tom/Downloads", "productdb.zip");&nbsp; &nbsp; var archive = ZipFile.OpenRead(filepath);&nbsp; &nbsp; var data = archive.Entries.Single(e => e.FullName == "productdb.json");&nbsp; &nbsp; var s = data.Open();&nbsp; &nbsp; return new MyStream(s, archive);}(可以稍微改进以确保archive在我们成功返回之前发生异常时已处理)
打开App,查看更多内容
随时随地看视频慕课网APP