C#日常优化2-内存泄漏

前言

在.Net Runtime源码提交记录中,看到一个issus,就是有关内存泄漏的,

有问题的代码

var jsonDocument = JsonDocument.Parse(json, new JsonDocumentOptions() { AllowTrailingCommas = true });
//仔细观察上面这一行代码,这一行会不会形成内存泄漏

正确的代码

using var jsonDocument = JsonDocument.Parse(json, new JsonDocumentOptions() { AllowTrailingCommas = true });
//和有问题代码,相对之前,就增加了using ,在使用完毕之后自动释放

性能基准测试

using System;
using System.Text.Json;
using BenchmarkDotNet.Attributes;

[DisassemblyDiagnoser(printSource: true, maxDepth: 3)]
[MemoryDiagnoser]
public class JsonDocumentTest
{
	[Params(128, 1024)]
	public int Count { get; set; }

	private string json;

	[GlobalSetup]
	public void Setup()
	{
		json = """
		{
			"code": "Tst-0003-015",
			"name": "测试物料",
			"status": 0,
			"statusName": "正常",
			"specification": "268",
			"brand": "",
			"unit": "",
			"isReel": false,
			"minCount": 0,
			"maxCount": 0,
			"remark": "",
			"paperWeight": 0,
			"openness": null,
			"paperMo": 0,
			"paperLength": 0,
			"paperWidth": 0,
			"length": 0,
			"width": 0,
			"height": 0,
			"ratio": 0,
			"price": 0,
			"tonPrice": 0,
			"squarePrice": 0,
			"id": 2000
		}
		""";
	}

	[Benchmark]
	public unsafe void Dispose()
	{
		int sum = 0;
		for (int i = 0; i < Count; i++)
		{
                       //使用using管理JsonDocument
			using var jsonDocument = JsonDocument.Parse(json, new JsonDocumentOptions() { AllowTrailingCommas = true });
			if (jsonDocument is not null)
			{
				sum += 1;
			}
		}

	}

	[Benchmark(Baseline = true)]
	public unsafe void NoDispose()
	{
		int sum = 0;
		for (int i = 0; i < Count; i++)
		{
                        //在将json转为JsonDocument后,为进行资源释放,最终在GC在内存不足时触发,释放资源
			var jsonDocument = JsonDocument.Parse(json, new JsonDocumentOptions() { AllowTrailingCommas = true }); 
			if (jsonDocument is not null)
			{
				sum += 1;
			}
		}
	}
}

使用using和非using在使用内存上的差异和性能对比

根据上图:

第一轮执行128次,耗时对比使用using比using快了56%,0代GC减少了差不多了31次,内存分配少了98%

第二轮执行1024次,耗时使用using比非using快了10%,0代GC减少了246次,内存分配少了98%,在内存上使用using可以让资源正常回收,减少GC回收的次数,

在两轮测试中,发现使用using和非using在内存上差异是很大的,使用using可以减少内存的占用,主要是资源回收比较及时,减少出发GC回收的次数

秋风 2026-04-02