Zac*_*ham 20 .net windows garbage-collection memory-management
安装程序
.NET为段中的每一代堆(0,1,2,LOH)分配内存,以便在启动时以及在集合之后尝试满足分配请求时获得连续的内存块.
为应用程序"预热"时,为每个堆分配的内存可能会趋于平稳,除了可能用于第2代和大对象堆.在垃圾收集期间,每个堆(0,1,2)都被扫描并压缩,除了大扫描的大对象堆(LOH).
我理解集合的"扫描"部分意味着GC识别哪些对象不再有根并且可用于收集(或完成),并且'compact'意味着堆中仍然存活的地址被重新组织,因此可用的剩余堆具有更多可用的连续内存.
由于超出了堆中每个段的预算,.NET将分配另一个段以便在可能的情况下完成分配.
问题
我的问题归结为每个堆中的内存会发生什么,应用程序(已提交)不再使用,但仍由.NET保留? 什么时候发布回操作系统?.
我认为这是一个过程可能会占用大量内存的场景(虚拟大小非常大,但私有字节很小),但是当检查它的堆大多是可用空间时.作为另一个警告,堆的总大小也可能非常小,并且不考虑该过程消耗的内存.
没有阻止的终结器,并且对于一个进程看起来都很健康 - 它可能已经运行了几周才触发监视器警报(例如).
试图进一步澄清这个问题,如果您阅读Tess .NET内存管理 - 餐馆类比,如果表是堆段,餐厅是否会丢失表(例如免费堆段)?
编辑
the*_*oop 10
我的回答是 - 没关系.操作系统为应用程序(运行.NET运行时)提供虚拟内存.这不是"真正的"记忆.操作系统可以将每页虚拟内存放在任何地方 - 在处理器上,主内存中,在磁盘上.因此,应用程序可以使用比系统上的RAM数量更多的内存,并且操作系统将复制磁盘所需的位以确保应用程序保持运行(模块化某些寻址和技术限制).
操作系统管理系统上所有进程的虚拟内存,并确保一个程序不会占用系统上的所有RAM而损害其他程序.当.NET运行时要求系统中的内存用于堆中,但是然后不使用它时,此内存将(如果系统空闲RAM较低)将被移动到磁盘,因为它没有被访问.
来自苔丝的电子邮件澄清:(强调我的)
在整个应用过程中,段大小保持不变,但这里有两件事需要考虑.
段的分配是虚拟分配,这意味着当我们保留虚拟内存时,我们只提交实际使用的内容,因此用于段的专用字节与段大小不同,这意味着在GC之后,您的私有字节将会关闭,而您的虚拟字节将保持不变.
当不再使用某个段时,即如果您发生某个段中的所有内容以使其不再包含任何.net对象,则将虚拟alloc返回给操作系统.
根据信仰,然后堆段(餐馆表)将返回到操作系统.