操作系统如何知道我的应用程序使用了多少内存?(为什么不进行垃圾收集呢?)

Jef*_*ang 5 garbage-collection operating-system memory-management

当我的任务管理器(top,ps,taskmgr.exe或Finder)说某个进程正在使用XXX KB的内存时,它究竟在计算什么,以及它是如何更新的?

在内存分配方面,用C++编写的应用程序是否与作为虚拟机运行的应用程序(如.NET或Java等托管代码)的操作系统"看起来"不同?

最后,如果内存是如此透明 - 为什么垃圾收集不是操作系统的功能或服务提供?


事实证明,我真正感兴趣的是为什么操作系统无法进行垃圾收集和碎片整理内存空间 - 我认为这只是"简单地"为进程分配地址空间.

这些答案有很多帮助!谢谢!

Mic*_*ael 4

这是一个很大的话题,我不能希望在这里用一个答案来充分回答。我建议您获取一份Windows Internals的副本,它是非常宝贵的资源。 Eric Lippert最近发表了一篇博客文章,很好地描述了如何查看操作系统分配的内存。

进程使用的内存基本上只是操作系统保留的地址空间,可能由物理内存、页面文件或文件支持。无论是托管应用程序还是本机应用程序,这都是一样的。当进程退出时,操作系统会删除为其分配的内存 - 虚拟地址空间被简单删除,页面文件或物理内存备份可供其他进程使用。这就是操作系统真正维护的全部内容——地址空间到某些物理资源的映射。当进程需要更多内存或空闲时,映射可能会发生变化 - 物理内存内容可以由操作系统转移到磁盘,反之亦然,以满足需求。

根据这些工具,进程正在使用的内容实际上可能意味着以下几件事之一:它可以是分配的总地址空间、分配的总内存(页面文件+物理内存)或进程实际使用的驻留在内存中的内存。任务管理器对于每种可能性都有一个单独的列。

操作系统无法进行垃圾收集,因为它无法了解内存实际包含的内容 - 它只看到分配的内存页,而看不到可能被引用或未被引用的对象。

尽管操作系统在虚拟地址级别处理分配,但在进程本身中还有其他内存管理器,它们获取这些大的、页面大小的块并将它们分解成对应用程序有用的东西。Windows 将返回在 64k 边界中分配的内存,但随后堆管理器将其分成更小的块,供程序通过new. 在 .Net 应用程序中,CLR 将从垃圾收集堆中移交新对象,并且当该堆达到其限制时,将执行垃圾收集。