Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
由.NET进程分配的内存何时释放回Windows_.net_Windows_Garbage Collection_Memory Management - Fatal编程技术网

由.NET进程分配的内存何时释放回Windows

由.NET进程分配的内存何时释放回Windows,.net,windows,garbage-collection,memory-management,.net,Windows,Garbage Collection,Memory Management,设置 NET在启动时以及在收集后尝试满足分配请求时,为每一代的堆(0、1、2、LOH)分段分配内存,以获得连续的内存块 当应用程序“升温”时,分配给每个堆的内存可能会趋于平稳,第2代和大型对象堆除外。在垃圾收集过程中,每个堆(0、1、2)都会被扫描和压缩,但大对象堆(LOH)除外,它刚刚被扫描 我理解集合的“扫描”部分意味着GC识别哪些对象不再是根对象,并且可用于收集(或最终确定)“紧凑”意味着对堆中仍然存在的地址进行重新组织,以便剩余的可用堆具有更多的连续内存 由于超出了堆中每个段的预算,.N

设置

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

当应用程序“升温”时,分配给每个堆的内存可能会趋于平稳,第2代和大型对象堆除外。在垃圾收集过程中,每个堆(0、1、2)都会被扫描和压缩,但大对象堆(LOH)除外,它刚刚被扫描

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

由于超出了堆中每个段的预算,.NET将分配另一个段,以便在可能的情况下完成分配

问题

我的问题归结到每个堆中的内存会发生什么变化,即应用程序不再使用(已提交),但仍由.NET保留何时将其释放回操作系统?

我认为在这种情况下,进程可能会消耗大量内存(虚拟大小相当大,但私有字节很小),但在检查其堆时,大部分是可用空间。另一个注意事项是,堆的总大小也可能非常小,,不考虑进程消耗的内存

没有被阻止的终结器,并且对于一个进程来说,所有终结器看起来都是正常的-它可能在触发监视器警报(例如)之前已经运行了数周

试图进一步澄清这个问题,如果您阅读Tess,如果桌子是堆段,餐厅是否曾经丢失过桌子(例如,空闲堆段)

编辑

  • 删除了对工作组和鸡的混淆引用
  • 增加了对苔丝餐厅类比的引用

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

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

    通过电子邮件澄清,来自:(强调矿山)

    整个应用程序的段大小保持不变,但这里有两件事要考虑。

  • 段的分配是一种虚拟分配,这意味着当我们保留虚拟内存时,我们只提交实际使用的内存,因此用于段的专用字节与段大小不同,这意味着在GC之后,您的专用字节将减少,而您的虚拟字节将保持不变

  • 当某个段不再使用时,即,如果您碰巧GC了该段中的所有内容,使其不再包含任何.net对象,则虚拟alloc将返回操作系统。


  • 相信这一点,那么堆段(餐厅桌子)将返回到操作系统

    我不知道这个问题的答案,但我怀疑.NET在进程退出之前不会释放其堆(可能是在卸载AppDomain时)。这仅基于我对perfmon.NET内存计数器的观察。GC总字节计数器显示,至少在我的应用程序中,保留字节在我的应用程序的生命周期中会有一点上下波动,大约30MB


    而且,如果GC在服务器模式下运行,那么.NET可能会更频繁地释放内存。

    我认为它不会向任何人请求任何保留内存(如果有时确实会发生这种情况)。据我所知,最小化只会导致Windows更愿意将该进程的内存交换到磁盘。请查看此网站:“这称为非确定性终结,您不能说何时调用对象的终结器。结果是,在对象本身不再被程序实际使用后,对象使用的任何内存或非托管资源都会在一段不确定的时间内保持分配状态。”@Martinho,Winform可能会挂接最小化消息并调用GC.Collect(),我不知道,但它可以。@Ian:这不是Windows要求的。这将是您自己的进程决定压缩堆,从而为您的进程保留更多未使用的内存。即使该内存是“空闲的”,它仍然属于您的进程,而不是操作系统。问题不在于何时发生垃圾回收,而在于垃圾回收器“释放”的内存何时返回操作系统。@Martinho-你说的对,我(错误地)记得的是进程“工作集”报告是通过最小化应用程序来实现的。虽然我普遍同意,特别是关于“无所谓”部分,这种行为确实会影响一些事情:交换文件有多大。我家的硬盘是1TB。交换文件中的一些额外MB(甚至1GB)并不重要。交换:交换文件的大小与大磁盘无关,但磁盘访问性能仍然可能是一个问题——因此更快(更智能)地释放内存和内存