配置
.NET为每个代的堆(0、1、2、LOH)分配内存段,以获得连续的内存块,在启动时和在尝试满足分配请求或集合后。除了可能会出现第二代和大对象堆之外,为每个堆分配的内存可能会随着应用程序“热身”而稳定。
在垃圾回收期间,每个堆(0、1、2)都被扫描和压缩,但大对象堆(LOH)只是被扫描。
我理解集合中的“扫描”部分是指GC识别不再与根连接并可供收集(或完成处理)的对象,“压缩”意味着仍然存在于堆中的地址进行重新组织,使剩余的可用堆具有更多连续的可用内存。
当堆内的每个段的预算超出时,.NET将分配另一个段,以便在可能的情况下满足分配。
问题
我的问题是:在每个堆中,如果应用程序不再使用(调用)其保留的内存,那么这些内存何时被释放回操作系统?
我认为这种情况可能会导致进程似乎消耗了大量内存(虚拟大小非常大,但私有字节很小),但检查其堆时大部分空间都是空闲的。另外,堆的总大小也可能相当小,不能解释进程正在消耗的内存。
没有被阻塞的终结器,所有内容都看起来健康 - 可能在触发监视器警报(例如)之前运行了数周。
为了进一步澄清问题,如果您阅读Tess的.NET内存管理——餐厅类比,如果桌子代表堆段,那么这家餐厅会失去桌子吗(例如,释放堆段)?
编辑
- 删除了有关工作集和鸡的混淆引用
- 添加了对Tess餐厅类比的引用