我的问题有点幼稚 . 我愿意尽可能简单地概述,找不到任何能让我清楚的资源 . 我是开发人员,我想了解Windows任务管理器中默认情况下“内存”列中显示的内存究竟是什么:
为了使事情变得更简单,让我们忘记进程与其他进程共享的内存,并想象共享内存可以忽略不计 . 此外,我专注于全局,主要关注GB级别的事物 .
据我所知,被称为“虚拟内存”的进程保留的内存部分存储在主内存(RAM)中,部分存储在磁盘上 . 系统决定了哪里去了 . 系统基本上在RAM中保留虚拟存储器的部分,该部分由该过程充分频繁地访问 . 进程可以保留比计算机中可用的RAM更多的虚拟内存 .
从开发人员的角度来看,虚拟内存只能由程序通过自己的内存管理器(例如 malloc()
或 new X()
)进行部分分配 . 我想系统不知道虚拟内存的哪个部分被分配,因为这是由进程以"private"方式处理的,并且取决于语言,运行时,编译器... Q: Is this correct?
我的假设是,任务管理器显示的内存基本上是系统存储在RAM中的虚拟内存的一部分 . Q: Is it correct? And is there a simple way to know the total virtual memory reserved by the process?
1 回答
Windows上的内存是......非常复杂,并且询问“我的进程使用了多少内存”实际上是一个荒谬的问题 . 要回答你的问题,请先了解一下背景知识 .
Windows上的内存通过
ptr = VirtualAlloc(..., MEM_RESERVE, ...)
分配,稍后通过VirtualAlloc(ptr+n, MEM_COMMIT, ...)
提交 .任何保留的内存只占用地址空间,所以没有意思 . Windows会让你
MEM_RESERVE
太字节的内存就好了 . 提交内存确实耗尽了资源,但却没有充分利用内存 . 但实际使用它之前,Windows内存管理器实际上并没有给你物理ram .然而,稍后,如果Windows对于物理RAM很紧,它会将一些RAM交换到磁盘(它可能会压缩它并丢弃未使用的页面,丢弃从文件和其他优化中直接映射的任何内容) . 这意味着您的程序的总提交和物理ram总使用量可能会大不相同 . 根据您测量的内容,这两个数字都很有用 .
's one last large caveat - memory that is shared. When you load DLLs the code, the read-only memory [and even maybe the read/write section but this is COW' d]可与其他程序共享 . 这意味着你的应用程序需要内存,但你无法仅仅依靠你的应用程序计算内存 - 毕竟它可以被共享,因此不会占用像天真计数那样多的物理内存 .
(如果您正在编写游戏或类似游戏,您还需要计算GPU内存,但我不是这里的专家)
所有上述优点通常都由应用程序使用的堆包装,你不会看到这一点 - 你要求并使用内存 . 它尽可能地优化 .
您可以通过转到详细信息选项卡并查看各种选项来看到这一点 - commit-size和working-set非常有用 . 如果您只是查看任务管理器中的主窗口并且它只有一个值,我希望您现在明白所使用的内存的单个值必须是某种妥协,因为它不是一个有意义的问题 .
现在回答你的问题
首先,操作系统确切地知道您的应用程序已预留了多少内存以及已提交的内存量 . 它不知道的是,你(或者更可能是CRT)正在使用的堆实现是否保留了一些未释放的内存,而这些内存尚未释放回操作系统 . 堆通常以优化方式执行此操作 - 从操作系统请求内存并将其释放回操作系统是一项相当昂贵的操作(并且只能在称为页面的大块中完成),因此大多数操作都会保留一些 .
第二个问题:不要使用该值,转到详细信息并使用其中的值,因为只有您知道您实际想要询问的内容 .
编辑:
对于您的评论,是的,但这取决于分配的大小 . 如果你分配了一个大的内存块(比如说> = 1MB),那么CRT中的堆通常会直接将分配推迟到操作系统,因此释放单个内存实际上会释放它们 . 对于小分配,CRT中的堆要求操作系统中的内存页,然后将其细分以分配给出 . 所以,如果你然后释放你丢失或泄露的其他每一个,它只是有效地汇集,如果分配要求这个大小,将再次使用 . 如果你关心这个记忆你可以使用crt heap statistics famliy of functions来关注那些 - 特别是
_CrtMemDumpStatistics