gpt4 book ai didi

C# 内存分配、GC、死对象不匹配的内存诊断

转载 作者:行者123 更新时间:2023-12-03 07:53:44 33 4
gpt4 key购买 nike

我对 C# 中的内存分配和垃圾收集方式有一定程度的了解。但即使在阅读了多篇文章并尝试了一些测试 C# 程序之后,我仍然对 GC 缺乏一些清晰的认识。为了简化问题,我创建了一个虚拟 ASP 核心 Web API 项目,其中包含一个包含一个 int 属性的 DummyPojo 类和一个创建数百万个 DummyPojo 对象的 DummyClass。即使在运行强制 GC 后,死对象也不会被收集。有人可以解释一下吗?

public class DummyPojo
{
public int MyInt { get; set; }
~DummyPojo() {
//Debug.WriteLine("Finalizer");
}
}
public class DummyClass
{
public async Task TestObjectsMemory()
{
await Task.Delay(1000 * 10);
CreatePerishableObjects();
await Task.Delay(1000 * 10);
GC.Collect();
}
private void CreatePerishableObjects()
{
for (int i = 0; i < 100000; i++)
{
DummyPojo obj = new() { MyInt = i };
}

}
}

然后在我的program.cs文件中,我刚刚调用了开始创建对象的方法。

DummyClass dc = new DummyClass();
_ = dc.TestObjectsMemory();

我运行该程序并使用 Visual Studio 的内存诊断工具拍摄了 3 个内存快照,每个快照等待 3 个 10 秒,一个在创建对象之前,第二个在创建对象之后,最后一个在触发 GC 之后。 enter image description here

我的问题是:

  1. 为什么内存使用量没有降到原来的大小?我知道 GC 仅在需要时才运行,就像内存紧缩一样。就我而言,我触发了 GC,并且我看到终结器也被调用。我期望 GC 收集死对象并压缩内存。据我了解,这与 LOH 无关,因为我没有使用任何大型对象或数组。请查看下面的图片了解每个快照和 GC 编号。 1st Snapshot 2nd Snapshot GC Run 3rd Snapshot

    • 第二个快照显示 118MB(从 114MB 跃升 4MB)是由于死对象造成的?
    • 为什么即使在强制 GC 之后,快照 3 中的内存也会跳至 125MB,而不是回到 114MB。
  2. 当内存不断增加时,快照差异显示为绿色,表示内存减少。为什么会显示相反的结果?

  3. 当我打开快照#3 时,我看到 DummyPojo 死亡对象。难道不应该被强制GC回收吗? pojo dead object

最佳答案

我对 VS 内存分析器不太熟悉,因此其中一些内容只是猜测。

首先,重要的是要记住您正在监视的内存类型。该图显示进程内存,我认为这意味着进程从操作系统分配的所有内存。当您分配更多对象时,该内存显然需要增加,但它不会与托管堆的大小(即您正在使用的实际内存)直接相关。 GC可以过度分配内存,以减少需要向操作系统请求内存的次数,并且除非确定一段时间内不再需要内存,否则不会将内存释放回操作系统。我主要使用dotMemory,它的图被分成每一代+LOH+非托管,使得GC的效果更容易看到。

与一些评论相反GC.Collect应该阻塞直到收集完成:

Use this method to try to reclaim all memory that is inaccessible. It performs a blocking garbage collection of all generations.

但是你声明了一个终结器,这意味着所有对象在被收集时都会被放入终结器队列中。因此,即使在被“收集”之后,它们也会保持半死不活的状态。终结器旨在确保收集非托管资源,这应该罕见。我真的建议在对 GC 进行任何类型的调查时删除终结器。如果不涉及终结器队列及其所带来的所有复杂性,GC 就很难理解。

另请注意,只要行为不变,编译器就可以进行任何优化。由于内存分配不被视为“行为”,因此允许删除整个循环。

关于C# 内存分配、GC、死对象不匹配的内存诊断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76552560/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com