我对以下代码有疑问。我在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;
}
}
}
}
答案 0 :(得分:3)
由于某种未知的原因,如果我转储对象,我会发现MemoryStream仍然在Main方法的末尾。
这不是特别的异常; GC单独发生。
这导致我大量泄漏。
这不是泄漏,而只是内存使用情况。
有什么主意我可以清理这个缓冲区吗?
我可能只是不使用MemoryStream
,而是返回一些包裹实时解压缩流的内容(来自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
(如果在我们成功返回之前发生异常,可以稍作改进以确保处置Dim pvt As PivotTable
Set pvt = ActiveSheet.PivotTables("PivotTable1")
ActiveSheet.PivotTables("PivotTable1").AllowMultipleFilters = True
With pvt.PivotFields("Heading 1")
.ClearAllFilters
.PivotFilters.Add2 Type:=xlValueIsGreaterThan, DataField:=ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum of Heading 2"), Value1:=2
End With
With pvt.PivotFields("Help 1")
.ClearAllFilters
.PivotFilters.Add2 Type:=xlValueIsSmallerThan, DataField:=ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum of Heading 2"), Value1:=11
End With
With pvt.PivotFields("Help 2")
.ClearAllFilters
.PivotFilters.Add2 Type:=xlValueIsGreaterThan, DataField:=ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum of Heading 3"), Value1:=4
End With
)