5
|
Jeff Meatball Yang · 技术社区 · 15 年前 |
![]() |
1
4
这是一个大问题,我不希望在这里用一个答案来充分回答。我建议取一份 Windows Internals 它是一种宝贵的资源。 Eric Lippert 最近有一篇博客文章,很好地描述了如何查看操作系统分配的内存。 一个进程正在使用的内存基本上只是 address space 由操作系统保留,可以由物理内存、页面文件或文件进行备份。无论是托管应用程序还是本机应用程序,这都是相同的。当进程退出时,操作系统会删除已分配给它的内存——虚拟地址空间只需删除,页面文件或物理内存备份可供其他进程使用。这是所有操作系统真正维护的——地址空间到某些物理资源的映射。映射可以随着进程需要更多内存或空闲而移动—物理内存内容可以移动到磁盘,操作系统也可以反过来移动以满足需求。 根据这些工具,一个进程正在使用的实际上可能意味着以下几点之一:它可以是分配的总地址空间、分配的总内存(页面文件+物理内存)或一个进程实际使用的内存(驻留在内存中)。任务管理器对于这些可能性都有单独的列。 操作系统不能进行垃圾收集,因为它无法洞察内存实际包含的内容——它只看到分配的内存页,看不到可能被引用或不被引用的对象。
虽然操作系统的句柄是在虚拟地址级别分配的,但是在进程本身中,还有其他内存管理器,它们将这些大的、页面大小的块分割成一些对应用程序有用的块。Windows将返回以64K边界分配的内存,但堆管理器将其分成更小的块,供程序通过
|
![]() |
2
2
我不能回答你的问题,关于内存如何出现在C++与虚拟机等方面的差异,但我可以说,应用程序通常在初始化时使用一定的内存范围。然后,如果应用程序需要更多,它将从操作系统请求它,并且操作系统(通常)将授予它。这有许多实现——在一些操作系统中,其他应用程序的内存被移走,以便为您提供一个更大的连续块,而在其他系统中,您的应用程序获得不同的内存块。甚至可能涉及到一些虚拟内存处理。这一切都取决于抽象的实现。在任何情况下,内存仍然被视为程序中的连续内存——操作系统至少会处理这么多。 对于垃圾收集,操作系统知道 界限 你的记忆,但不是你内心的东西。此外,即使它确实查看了应用程序使用的内存,它也不知道超出范围的变量使用了什么块,以及GC正在查找什么块。 |
![]() |
3
2
主要区别在于应用程序管理。微软将其区分为托管和非托管。当对象分配到内存中时,它们存储在特定的地址。对于托管和非托管应用程序都是如此。在托管世界中,“地址”被包装在对象句柄或“引用”中。 当内存被VM垃圾收集时,它可以安全地挂起应用程序,在内存中移动对象,并更新所有“引用”以指向它们在内存中的新位置。 在Win32样式的应用程序中,指针是指针。操作系统无法知道它是一个对象、一个任意的数据块、一个普通的32位值等,因此它无法对对象之间的指针进行任何推断,因此它无法在内存中移动它们或更新对象之间的指针。 由于引用的处理方式,操作系统不能接管GC进程,而是由虚拟机来管理应用程序使用的内存。因此,虚拟机应用程序在操作系统中的表现完全相同。它们只需要请求内存块就可以使用,操作系统会将其提供给它们。当vm执行gc并压缩它的内存时,它可以将内存释放回操作系统供另一个应用程序使用。 |
![]() |
TheKing · 为什么数组的地址可以有负值? 3 年前 |
![]() |
yurnero · MATLAB:“加载”一个快速访问功能 6 年前 |
![]() |
joe · 一页可以同时在两个工作集中吗? 6 年前 |
![]() |
Jaques · “.exe”已触发断点 6 年前 |
![]() |
adn bps · 在函数中修改变量的高效内存方法 6 年前 |
![]() |
Gauraang Khurana · C语言中分段错误的不稳定行为 6 年前 |
![]() |
Rajesh K · 如何查找设备中存在的广告垃圾? 6 年前 |