由 .NET 进程分配的内存何时释放回 Windows [英] When is memory, allocated by .NET process, released back to Windows

查看:17
本文介绍了由 .NET 进程分配的内存何时释放回 Windows的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

设置

.NET 为每一代的堆(0、1、2、LOH)分段分配内存以获得连续的内存块,在启动时以及在收集后尝试满足分配请求时.

.NET allocates memory for each generation’s heap (0, 1, 2, LOH) in segments to get a continuous block of memory, on startup, and when it attempts to satisfy an allocation request, after a collection.

为每个堆分配的内存可能会随着应用程序热身"而趋于平稳,除了可能用于第 2 代和大型对象堆.在垃圾回收期间,每个堆 (0, 1, 2) 都会被清扫和压缩,但大对象堆 (LOH) 除外,它只是被清扫.

This memory allocated for each heap will likely level off as the application "warms up", except potentially for generation 2, and large object heap. During a garbage collection, each heap (0, 1, 2) is swept and compacted, except for the large object heap (LOH), which is just swept.

我理解集合的扫描"部分意味着 GC 识别哪些对象不再是根对象并且可用于收集(或终结),并且紧凑"意味着在堆中仍然存在的地址被重新组织,以便可用的剩余堆具有更多可用的连续内存.

I understand the ‘sweep’ part of a collection to mean that the GC identifies which objects are no longer rooted and are available for collection (or finalization) and that ‘compact’ means that the addresses that are still alive in a heap are reorganized so that the available remaining heap has more continuous memory available to it.

当超出堆内每个段的预算时,.NET 将分配另一个段以尽可能满足分配.

As the budget for each segment within the heap is exceeded, .NET will allocate another segment in order to fulfill allocations if it can.

问题

我的问题归结为每个堆中的内存会发生什么,即 不再被应用程序使用(已提交),但仍由 .NET 保留?什么时候发布回操作系统?.

My question comes down to what happens to that memory in each heap, that is not be used by the application (committed) any longer, but is still reserved by .NET? When is it released back to the OS?.

我认为这是一个进程可能会消耗大量内存(虚拟大小很大,但私有字节很小),但在检查其堆时大部分是可用空间.作为另一个警告,堆的总大小也可能非常小,并且不考虑进程消耗的内存.

I believe this to be the scenario where a process might appear to be consuming a lot of memory (virtual size is quite large, but private bytes small), but when inspecting its heaps are mostly free space. As another caveat, the total size of the heaps may also be quite small, and not account for the memory being consumed by the process.

没有阻塞的终结器,并且所有进程看起来都很健康 - 它可能在触发监视器警报之前已经运行了数周(例如).

There is no blocked finalizer and all looks healthy for a process - it may have been running for weeks before it triggered a monitor alert (e.g.).

如果您阅读 Tess .NET 内存管理 - 餐厅类比,如果表是堆段,餐厅是否会丢失表(例如空闲堆段)?

Trying for further clarification of the question, if you read Tess .NET Memory Management - A Restaurant Analogy, if the tables are heap segments, does the restaurant ever lose tables (e.g. free heap segments)?

编辑

  1. 删除了对工作集和鸡的混淆参考
  2. 添加了对 Tess 餐厅类比的参考

推荐答案

我的答案是——没关系.操作系统为应用程序(在其中运行 .NET 运行时)提供虚拟内存.这不是真实"的记忆.操作系统可以将虚拟内存的每一页放在它喜欢的任何地方——处理器上、主内存中、磁盘上.因此,应用程序使用的内存可能超过系统上的 RAM 量,并且操作系统会将所需的位复制到磁盘或从磁盘复制以确保应用程序继续运行(以某些寻址和技术限制为模).

My answer is - it doesn't matter. The OS gives the application (within which the .NET runtime runs) virtual memory. This is not 'real' memory. The OS can put each page of virtual memory wherever it likes - on the processor, in main memory, on the disk. So, it is possible for an app to use more memory than the amount of RAM on the system, and the OS will copy the bits that are needed to/from disk to ensures the app keeps running (modulo certain addressing & technical limitations).

操作系统管理系统上所有进程的虚拟内存,并确保一个程序不会占用系统上的所有 RAM 以损害其他程序.当 .NET 运行时向系统请求在堆中使用的内存,但随后没有使用它时,该内存将(如果系统的可用 RAM 不足)被移动到磁盘,因为它没有被访问.

The OS manages the virtual memory of all the processes on the system, and ensures that one program doesn't hog all the RAM on the system to the detriment of other programs. When the .NET runtime asks for memory from the system for use in the heaps, but then doesn't use it, this memory will (if the system is low on free RAM) be moved to disk, because it isn't being accessed.

Tess 的电子邮件澄清:(强调我的)

Clarification via email from Tess: (emphasis mine)

段大小在整个申请过程中保持不变,但这里有两点需要考虑.

The segment sizes stay the same throughout the course of the application, but there are two things to consider here.

  1. 段的分配是虚拟分配,这意味着当我们保留虚拟内存时,我们只提交我们的实际使用,因此用于段的 私有字节 与段大小不同,这意味着在 GC 之后,您的私有字节将下降,而您的虚拟字节将保持不变.

  1. The allocations for a segment is a virtual allocation, meaning that while we reserve virtual memory, we only commit what we actually use, so the private bytes used for a segment is not the same as the segment size, this means that after a GC, your private bytes will go down, while your virtual bytes will stay the same.

当不再使用段时,即如果你碰巧对段中的所有内容进行 GC,使其不再包含任何 .net 对象,则将虚拟分配返回给操作系统.

相信这一点,堆段(餐厅表)将返回给操作系统.

Taking that on faith, then heap segments (restaurant tables) will be returned back to the OS.

这篇关于由 .NET 进程分配的内存何时释放回 Windows的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆