我的问题有点天真。我愿意有一个尽可能简单的概述,并没有找到任何资源,使我清楚。我是一名开发人员,我想了解Windows任务管理器中默认情况下“内存”列中显示的内存究竟是什么:

为了使事情变得更简单,让我们忘记进程与其他进程共享的内存,并设想共享内存可以忽略不计。此外,我专注于大局,主要关注GB级别的事情。
据我所知,由进程“虚拟内存”保留的内存部分存储在内存(RAM)中,部分存储在磁盘上。系统决定了哪里去了。该系统基本上保持在RAM中的部分虚拟内存是足够频繁地被访问的进程。一个进程可以保留比计算机中可用的RAM更多的虚拟内存。
从开发人员的角度来看,虚拟内存只能由程序通过自己的内存管理器(例如malloc()或new X() )部分分配。我想系统不知道分配了虚拟内存的哪一部分,因为这是由进程以“私有”的方式处理的,并且取决于语言、运行时、编译器.问:是对的吗?
我的假设是,任务管理器显示的内存实质上是系统存储在RAM中的虚拟内存的一部分。问:对吗?是否有一种简单的方法可以知道进程所保留的全部虚拟内存?
发布于 2018-05-18 10:39:44
窗户上的记忆是..。非常复杂的问题,问‘我的进程使用了多少内存’实际上是一个荒谬的问题。为了回答你的问题,让我们先了解一些背景知识。
windows上的内存通过ptr = VirtualAlloc(..., MEM_RESERVE, ...)分配,稍后使用VirtualAlloc(ptr+n, MEM_COMMIT, ...)提交。
任何保留的内存都会占用所有的地址空间,所以没有意义。Windows将使您的内存容量达到MEM_RESERVE万亿字节。提交内存确实会耗尽资源,但不会以您想象的方式使用。当您调用提交窗口时,做一些和,基本上算出(总物理内存+总交换-当前提交),并允许您分配内存,如果有足够的空闲。但是在实际使用之前,windows内存管理器实际上不会给您物理内存。
但是,如果windows对物理RAM比较紧,它会将部分RAM交换到磁盘上(它可能压缩内存并丢弃未使用的页面,丢弃从文件和其他优化中直接映射的任何内容)。这意味着您的程序的总提交和总物理ram的使用可能有很大的不同。这两个数字都是有用的,取决于您正在测量的是什么。
还有最后一个重要的警告--共享内存。当您加载DLL代码时,只读内存,甚至可能是读/写部分--但这是奶牛--可以与其他程序共享。这意味着你的应用程序需要这个内存,但是你不能仅仅用你的应用来计算内存--毕竟它可以被共享,所以不会像一个天真的计数那样占用那么多的物理内存。
(如果你正在写一个游戏或类似的游戏,你也需要计算GPU内存,但我不是这里的专家)
上面的所有优点通常都是由应用程序使用的堆包起来的,而您没有看到这一切--您请求并使用内存。而这也是最优的。
通过查看details选项卡并查看各种选项,您可以看到这一点--提交大小和工作集非常有用。如果你看一下任务管理器的主窗口,它有一个单一的值,我希望你现在明白,一个内存的单一值必须是某种妥协,因为它不是一个有意义的问题。
现在回答你的问题
首先,操作系统确切地知道您的应用程序保留了多少内存,以及它提交了多少内存。它不知道的是,您正在使用的堆实现(或者更可能是CRT)是否保留了一些尚未释放回操作系统的内存。堆通常是作为一种优化来实现的--要求从操作系统中获得内存并将其释放回操作系统是一项相当昂贵的操作(并且只能在称为页面的大块块中完成),因此它们中的大多数都保留了一些内存。
第二个问题:不要使用这个值,去细节,使用那里的价值,因为只有你知道你真正想要问什么。
编辑:
对于您的评论,是的,但这取决于分配的大小。如果您分配了一个大的内存块(例如>= 1MB),那么CRT中的堆通常直接将分配延迟到操作系统,因此释放单个内存实际上会释放它们。对于小的分配,CRT中的堆要求从操作系统中获取内存页,然后再细分,以便在分配中分配。因此,如果您然后释放其中的每一个,您将留下洞-堆不能把这些洞还给操作系统,因为操作系统通常只在整个页面中工作。因此,您在任务管理器中看到的任何内容都将显示所有内存仍然被使用。记住,这个内存不是丢失或泄漏的,它只是有效地被池化,如果分配要求这个大小,它将再次被使用。如果您关心这个内存,您可以使用crt堆统计函数族来监视那些-特别是_CrtMemDumpStatistics。
https://stackoverflow.com/questions/50408105
复制相似问题