mono/.Net GC会在收集后将免费分配的内存释放回操作系统吗?如果没有,为什么?

Pet*_*etr 6 c# memory garbage-collection

我曾多次听说,一旦C#托管程序从操作系统请求更多内存,它就不会释放它,除非系统内存不足.例如.当收集对象时,它被删除,对象占用的内存可以被另一个托管对象自由重用,但内存本身不会返回给操作系统(例如,unix上的mono不会调用brk/ sbrk减少进程可用的虚拟内存量,恢复到分配之前的状态.

我不知道这是否真的发生了,但是我可以看到我在linux上运行的c#应用程序在开始时使用少量内存,然后当我做一些内存昂贵的事情时,它会分配更多内存,但后来又当所有对象都被删除时(我可以通过将调试消息放入析构函数来验证),内存不会被释放.另一方面,当我再次运行内存昂贵的操作时,不再分配更多的内存.该程序只是继续吃相同数量的内存,直到它被终止.

也许这只是我对.net中的GC如何工作的误解,但如果真的像这样工作,为什么呢?保留分配的内存以供以后使用,而不是将其返回给系统有什么好处?它怎么能知道系统是否需要它?那么因为这种效应导致OOM崩溃或无法启动的其他应用程序怎么办?

我知道人们可能会回答类似"GC管理内存比以往任何时候都更好,只是不关心它"或"GC知道它做得最好"或"它根本不重要,它只是虚拟内存" "但是它确实很重要,在我的2gb笔记本电脑上运行OOM(内核OOM杀手就是因为这个而开始)因为这种不负责任的内存管理,经常在我运行任何C#应用程序之后.

注意:我在linux上单声道测试这个因为我真的很难理解windows如何管理内存,所以linux上的调试对我来说要容易得多,linux内存管理也是开源代码,windows内核/ .Net的内存管理对我来说相当神秘

Guf*_*ffa 4

内存管理器以这种方式工作,因为当您不需要时,拥有大量未使用的系统内存没有任何好处。

如果内存管理器总是尝试分配尽可能少的内存,那就意味着它会无缘无故地做很多工作。它只会减慢应用程序的速度,唯一的好处是没有应用程序使用更多的可用内存。

每当系统需要更多内存时,它就会告诉正在运行的应用程序返回尽可能多的内存。当您最小化应用程序时,也会将相同的信号发送到应用程序。

如果这在 Linux 中与 Mono 的工作方式不同,那么那就是该特定实现的问题。