mono /.Net GC在收集后释放空闲分配的内存回给操作系统?如果不是,为什么?
本文关键字:内存 操作系统 分配 如果不 为什么 GC Net 放空 释放 mono | 更新日期: 2023-09-27 18:08:36
我听说过很多次,一旦c#托管程序从操作系统请求更多的内存,它不会释放它,除非系统内存不足。如。当对象被收集时,它被删除,并且被对象占用的内存可以被另一个托管对象重用,但是内存本身不会返回给操作系统(例如,unix上的mono不会调用brk
/sbrk
来减少进程可用的虚拟内存数量,使其恢复到分配之前的数量)。
我不知道这是否真的发生了,但我可以看到我的c#应用程序,在linux上运行,在开始时使用少量内存,然后当我做一些内存昂贵的事情时,它分配更多的内存,但后来当所有对象被删除时(我可以通过将调试消息放入析析函数来验证),内存没有被释放。另一方面,当我再次运行内存昂贵的操作时,不会分配更多的内存。程序只是继续消耗相同数量的内存,直到它被终止。
也许这只是我对。net中GC工作方式的误解,但如果它真的像这样工作,为什么呢?保留已分配的内存以供以后使用,而不是将其返回给系统,这有什么好处?它怎么知道系统是否需要它呢?由于此影响导致的OOM而导致崩溃或无法启动的其他应用程序怎么办?
我知道人可能会回答类似"GC管理内存比你可以,只是不关心"或"GC知道它最擅长的"或"没关系,这只是虚拟内存"但它,在我的2 gb的笔记本我伯父运行(和内核伯父杀手开始因为)经常当我任何c#应用程序运行一段时间后,正是因为这种不负责任的内存管理。
注意:我在linux的mono上测试这一切,因为我真的很难理解windows是如何管理内存的,所以在linux上调试对我来说容易得多,而且linux内存管理是开源代码,windows内核/.Net的内存管理对我来说相当神秘
内存管理器是这样工作的,因为当您不需要大量未使用的系统内存时,没有任何好处。
如果内存管理器总是尝试分配尽可能少的内存,那就意味着它会无缘无故地做很多工作。它只会减慢应用程序的速度,唯一的好处是没有应用程序使用更多的空闲内存。
当系统需要更多内存时,它会告诉正在运行的应用程序返回尽可能多的内存。当你将它最小化时,同样的信号也会发送到应用程序。
如果这与Linux中的Mono不一样,那么这是特定实现的问题。
一般来说,如果一个应用程序需要一次内存,它将再次需要它。将内存释放回操作系统只是为了再次请求它是开销,如果没有其他东西需要内存:为什么要麻烦呢?。它正试图为很可能再次想要它的情况进行优化。此外,释放它需要整个/连续的块可以交还,这对压缩等事情有非常具体的影响:它不像"嘿,我没有使用大部分:把它拿回来"那么简单——它需要弄清楚哪些块可以被释放,大概是在一个完整的收集和压缩(重新定位对象等)周期之后。