简体   繁体   English

Windows Task Manager显示进程虚拟内存的哪个部分

[英]What part of the process virtual memory does Windows Task Manager display

My question is a bit naive. 我的问题有点天真。 I'm willing to have an overview as simple as possible and couldn't find any resource that made it clear to me. 我愿意提供一个尽可能简单的概述,并且找不到任何使我明白的资源。 I am a developer and I want to understand what exactly is the memory displayed in the "memory" column by default in Windows Task Manager: 我是一名开发人员,我想了解Windows Task Manager中默认情况下“内存”列中显示的内存到底是什么:

在此处输入图片说明

To make things a bit simpler, let's forget about the memory the process shares with other processes, and imagine the shared memory is negligible. 为了使事情简单一些,让我们忘记该进程与其他进程共享的内存,并假设共享内存可以忽略不计。 Also I'm focussed on the big picture and mainly care for things at GB level. 我也专注于全局,主要关心GB级别的事物。

As far as I know, the memory reserved by the process called "virtual memory", is partly stored in the main memory (RAM), partly on the disk. 据我所知,进程“虚拟内存”保留的内存部分存储在主内存(RAM)中,部分存储在磁盘上。 The system decides what goes where. 系统决定去哪里。 The system basically keeps in RAM the parts of the virtual memory that is accessed sufficiently frequently by the process. 系统基本上将虚拟内存的一部分保存在RAM中,该进程会足够频繁地对其进行访问。 A process can reserve more virtual memory than RAM available in the computer. 一个进程可以保留比计算机中可用RAM更多的虚拟内存。

From a developer point of view, the virtual memory may only be partially allocated by the program through its own memory manager (with malloc() or new X() for example). 从开发人员的角度来看,虚拟内存只能由程序通过其自己的内存管理器(例如,使用malloc()new X()进行部分分配。 I guess the system has no awareness of what part of the virtual memory is allocated since this is handled by the process in a "private" way and depends on the language, runtime, compiler... Q: Is this correct? 我猜系统不知道虚拟内存的分配部分,因为这是由进程以“私有”方式处理的,并且取决于语言,运行时,编译器...问: 这正确吗?

My hypothesis is that the memory displayed by the task manager is essentially the part of the virtual memory being stored in RAM by the system. 我的假设是,任务管理器显示的内存实质上是系统存储在RAM中的虚拟内存的一部分。 Q: Is it correct? 问:对吗? And is there a simple way to know the total virtual memory reserved by the process? 有没有一种简单的方法来知道该进程保留的虚拟内存总量?

Memory on windows is... extremely complicated and asking 'how much memory does my process use' is effectively a nonsensical question. Windows上的内存非常复杂……询问“我的进程使用了​​多少内存”实际上是一个荒谬的问题。 TO answer your questions lets get a little background first. 要回答您的问题,请先获得一些背景知识。

Memory on windows is allocated via ptr = VirtualAlloc(..., MEM_RESERVE, ...) and committed later with VirtualAlloc(ptr+n, MEM_COMMIT, ...) . Windows上的内存是通过ptr = VirtualAlloc(..., MEM_RESERVE, ...)稍后再通过VirtualAlloc(ptr+n, MEM_COMMIT, ...)

Any reserved memory just uses up address space and so isn't interesting. 任何保留的内存都只会占用地址空间,因此没有兴趣。 Windows will let you MEM_RESERVE terabytes of memory just fine. Windows将允许您MEM_RESERVE TB的内存。 Committing the memory does use up resources but not in the way you'd think. 提交内存确实会浪费资源,但不会以您认为的方式使用。 When you call commit windows does a few sums and basically works out (total physical ram + total swap - current commit) and lets you allocate memory if there's enough free. 当您调用commit窗口时,它们会进行一些累加并基本计算出(总物理内存+总交换数-当前提交),并且如果有足够的可用空间,则可以分配内存。 BUT the windows memory manager doesn't actually give you physical ram until you actually use it. 但是,在您实际使用Windows内存管理器之前,它实际上并没有给您提供物理内存。

Later, however, if windows is tight for physical RAM it'll swap some of your RAM out to disk (it may compress it and also throw away unused pages, throw away anything directly mapped from a file and other optimisations). 但是,稍后,如果Windows占用的物理RAM太紧,它将把您的部分RAM交换到磁盘上(它可能会压缩它,还会丢弃未使用的页面,丢弃直接从文件映射的内容以及进行其他优化)。 This means your total commit and total physical ram usage for your program may be wildly different. 这意味着您的程序的总提交和总的物理内存使用情况可能完全不同。 Both numbers are useful depending on what you're measuring. 这两个数字都非常有用,具体取决于您要测量的内容。

There'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] can be shared with other programs. 当您加载DLL代码时,可以与其他程序共享只读存储器[甚至可能是读/写部分,但这是COW'd]。 This means that your app requires that memory but you cannot count that memory against just your app - after all it can be shared and so doesn't take up as much physical memory as a naive count would think. 这意味着您的应用程序需要该内存,但您不能仅将其计算在您的应用程序中-毕竟它可以共享,因此占用的物理内存不会像幼稚的计数那样。

(If you are writing a game or similar you also need to count GPU memory but I'm no expert here) (如果您正在编写游戏或类似游戏,则还需要计算GPU内存,但我不是专家)

All of the above goodness is normally wrapped up by the heap the application uses and you see none of this - you ask for and use memory. 以上所有优点通常由应用程序使用的堆包装,您看不到这些-您需要并使用内存。 And its just as optimal as possible. 并且它尽可能地最佳。

You can see this by going to the details tab and looking at the various options - commit-size and working-set are really useful. 您可以通过转到详细信息选项卡并查看各种选项来查看此内容-提交大小和工作集非常有用。 If you just look at the main window in task-manager and it has a single value I'd hope you understand now that a single value for memory used has to be some kind of compromise as its not a question that makes sense. 如果您仅查看任务管理器中的主窗口,并且它具有单个值,那么我希望您现在已经理解,所用内存的单个值必须是某种折衷方案,因为这不是一个有意义的问题。

Now to answer your questions 现在回答您的问题

Firstly the OS knows exactly how much memory your app has reserved and how much it has committed. 首先,操作系统确切知道您的应用程序已保留多少内存以及已提交多少内存。 What it doesn't know is if the heap implementation you (or more likely the CRT) are using has kept some freed memory about which it hasn't released back to the operation system. 不知道的是您(或更可能是CRT)使用的堆实现是否保留了一些尚未释放回操作系统的释放内存。 Heaps often do this as an optimisation - asking for memory from the OS and freeing it back to the OS is a fairly expensive operation (and can only be done in large chunks known as pages) and so most of them keep some around. 堆通常将其作为一种优化-从操作系统中请求内存并将其释放回操作系统是一项相当昂贵的操作(只能在称为页面的大块中完成),因此它们中的大多数都保留了一些空间。

Second question: Dont use that value, go to details and use the values there as only you know what you actually want to ask. 第二个问题:不要使用该值,而要详细了解并在其中使用这些值,因为只有您知道自己实际要问什么。

EDIT: 编辑:

For your comment, yes, but this depends on the size of the allocation. 对于您的评论,是的,但这取决于分配的大小。 If you allocate a large block of memory (say >= 1MB) then the heap in the CRT generally directly defers the allocation to the operating system and so freeing individual ones will actually free them. 如果您分配很大的内存块(例如> = 1MB),那么CRT中的堆通常会直接推迟对操作系统的分配,因此释放单个内存实际上将释放它们。 For small allocations the heap in the CRT asks for pages of memory from the operating system and then subdivides that to give out in allocations. 对于小分配,CRT中的堆从操作系统请求内存页,然后将其细分以分配。 And so if you then free every other one of those you'll be left with holes - and the heap cannot give those holes back to the OS as the OS generally only works in whole pages. 因此,如果您再释放其他所有漏洞,那么您将留下漏洞-并且堆无法将漏洞归还给操作系统,因为操作系统通常只能在整个页面上工作。 So anything you see in task manager will show that all the memory is still used. 因此,您在任务管理器中看到的所有内容都将显示所有内存仍在使用中。 Remember this memory isn't lost or leaked, its just effectively pooled and will be used again if allocations ask for that size. 请记住,此内存不会丢失或泄漏,它只是有效地池化了,如果分配要求该大小,它将再次使用。 If you care about this memory you can use the crt heap statistics famliy of functions to keep an eye on those - specifically _CrtMemDumpStatistics 如果您关心此内存,则可以使用函数crt堆统计信息来关注这些信息-特别是_CrtMemDumpStatistics

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何获取 Windows 中每个正在运行的进程的“专用 GPU 内存”编号(与 Windows 任务管理器中显示的编号相同) - How to get the "Dedicated GPU memory" number for every running process in Windows (The same numbers that are shown in the Windows Task Manager) 访问windows 10任务管理器进程列表 - Accessing windows 10 task manager process list 终止Qt过程:Windows任务管理器在做什么我不是? - Terminate Qt Process: What's Windows Task Manager doing that I'm not? C++ - Windows - 从任务管理器中捕获进程退出 - C++ - Windows - catch process exit from Task Manager Windows任务管理器确定程序的内存使用情况有多可靠? - How reliable is windows task manager for determining memory usage of programs? 扩展任务管理器Windows 8 - Extending Task Manager Windows 8 互斥锁会锁定内存的哪一部分? (p线程) - What part of memory does a mutex lock? (pthreads) 在任务管理器中隐藏进程 - Hide a process from Task Manager 在任务管理器上看到分配的 memory - Allocated memory seen on Task Manager 有什么方法可以确定一个(多)线程/任务的堆栈地址在 Linux 上的进程的虚拟 memory 中开始? - Is there any way to determine a (multi) thread/task's stack address start in the virtual memory of a process on Linux?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM