简体   繁体   English

监视器未显示正确的内存使用情况

[英]Monitor not showing the right memory usage

I want to know how I can use the resource monitor, any kind, htop top , etc. to track the memory usage of a processes.我想知道如何使用资源监视器、任何类型的htop top等来跟踪进程的内存使用情况。 Let's write a simple C program.让我们编写一个简单的 C 程序。

int main() {
    while(1){}
    return 0;
}

After the compilation, the executable output a.out is only 16Kb编译后可执行输出a.out只有16Kb

$ ls -lah ./a.out                                                                                                                                           [8:43:44]
-rwxr-xr-x  1 user  staff    16K May 17 08:43 ./a.out

As I understood, the code has no variable, no malloc and all kinds of statement that requires any additional memory usage other than the code itself, which will be loaded to the memory when running.据我了解,该代码没有变量,没有malloc和各种需要使用除代码本身之外的任何额外内存使用的语句,这些语句将在运行时加载到内存中。 Some additional memory for stack pointer, frame pointer, etc. is expected but shouldn't be too much.堆栈指针、帧指针等的一些额外内存是预期的,但不应太多。

Interestingly, when I run the code.有趣的是,当我运行代码时。 The System Monitor gives a very different opinion.系统监视器给出了非常不同的意见。

So I am using MacOS, the monitor states that the Virtual Memory usage is 30Gb+ !所以我使用的是 MacOS,显示器显示虚拟内存使用量为30Gb+ MacOS System Monitory 的屏幕截图,显示正在运行的进程消耗 30.54Gb 内存的使用情况

Okey?!好吗?! Maybe this is due to some optimization, or some unique technique that MacOS manages memory.这可能是由于一些优化,或者 MacOS 管理内存的一些独特技术。 Let's try running that in a Ubuntu Virtual Machine with 1Gb memory.让我们尝试在具有 1Gb 内存的 Ubuntu 虚拟机中运行它。

Ubuntu中top命令的屏幕截图,其中进程消耗2356kb内存

I know this looks more reasonable than 30Gb, but 2356Kb?我知道这看起来比 30Gb 更合理,但是 2356Kb?

Am I looking at the wrong indicator?我看错了指标吗?

As I understood, the code has no variable, no malloc and all kinds of statement that requires any additional memory usage other than the code itself, which will be loaded to the memory when running.据我了解,该代码没有变量,没有 malloc 和各种需要使用除代码本身之外的任何额外内存使用的语句,这些语句将在运行时加载到内存中。

Your code doesn't have much;你的代码没有太多; but your code is typically linked with some startup code that does things like preprocess command line arguments, initialize parts of the C library, and call your main() .但是您的代码通常与一些启动代码链接,这些代码执行预处理命令行参数、初始化 C 库的部分以及调用您的main()等操作。

You'll also have a stack (eg so that the startup code can call your main() ) that consumes memory (whether you use it or not).您还将有一个消耗内存(无论您是否使用它)的堆栈(例如,以便启动代码可以调用您的main() )。

When your program is started the executable loader will also "load" (map into your virtual address space) any shared libraries (eg C standard library, that's likely needed by the startup code you didn't write, even if you don't use it yourself).当您的程序启动时,可执行加载器还将“加载”(映射到您的虚拟地址空间)任何共享库(例如 C 标准库,这可能是您未编写的启动代码所需要的,即使您不使用自己做)。

The other thing that can happen is that when the startup code initializes the C standard library, the C standard library can initialize the heap (for things like malloc() ), and something (the rest of C standard library initialization, the remainder of the startup code) could use malloc() even though the code you didn't write doesn't use it.可能发生的另一件事是,当启动代码初始化 C 标准库时,C 标准库可以初始化堆(对于malloc()之类的东西)和一些东西(C 标准库初始化的其余部分,C 标准库的其余部分)启动代码)可以使用malloc()即使您没有编写的代码不使用它。

Of course operating systems/virtual memory management uses pages;当然操作系统/虚拟内存管理使用页面; so the size of each of your program's sections ( .text , .data , etc), each section in each shared library, your stack, your heap, etc;所以程序的每个部分( .text.data等)、每个共享库中的每个部分、堆栈、堆等的大小; are rounded up to the page size.向上舍入到页面大小。 Depending on which computer it is, page size might be 4 KiB (16 KiB for recent ARM/M1 Apple machines);根据它是哪台计算机,页面大小可能为 4 KiB(最近的 ARM/M1 Apple 机器为 16 KiB); and if the startup code you didn't create wants 1 byte in the .data section it costs 4 KiB (or 16 KiB) of memory.如果您没有创建的启动代码需要.data部分中的 1 个字节,则它需要 4 KiB(或 16 KiB)的内存。

So I am using MacOS, the monitor states that the Virtual Memory usage is 30Gb+!所以我使用的是 MacOS,显示器显示虚拟内存使用量为 30Gb+!

I'd guess that most of it is space that was allocated for heap;我猜大部分是为堆分配的空间; where a tiny amount of the space is used and most isn't.使用了少量空间而大部分没有使用的地方。 If you assume that there's 176 KiB of private memory (used by your program and its startup code) and 440 KiB of shared memory (used by shared libraries), and assume that "32.54 GiB" is 3412000000 KiB;如果您假设有 176 KiB 的私有内存(由您的程序及其启动代码使用)和 440 KiB 的共享内存(由共享库使用),并假设“32.54 GiB”为 3412000000 KiB; then maybe it's "3412000000 - (176 + 440) = 3411999384 KiB of space that was allocated but isn't actually being used".那么它可能是“3412000000 - (176 + 440) = 3411999384 KiB 的空间已分配但实际上并未被使用”。

I know this looks more reasonable than 30Gb, but 2356Kb?我知道这看起来比 30Gb 更合理,但是 2356Kb?

Continuing the assumption that it's mostly "allocated but not used" heap space;继续假设它主要是“已分配但未使用”的堆空间; it's good to understand how heap works.了解堆是如何工作的很好。 "Allocated but not used" space costs almost nothing, but asking the OS to allocate space (eg because the program actually used it all and ran out of "allocated but not used" space) involves some overhead. “已分配但未使用”的空间几乎没有成本,但要求操作系统分配空间(例如,因为程序实际使用了所有空间并且用完了“已分配但未使用”的空间)会产生一些开销。 For this reason the C library tends to ask the OS for large pieces of "allocated but not used" space (to minimize the overhead by reducing the chance of needing to ask the OS for more space) and then splits it into tiny pieces when you call malloc() .出于这个原因,C 库倾向于向操作系统询问大块“已分配但未使用”的空间(通过减少需要向操作系统询问更多空间的机会来最小化开销),然后在您使用时将其拆分为小块调用malloc()

With this in mind;考虑到这一点; and not forgetting that the startup code and libraries are "generic" and not likely to by optimized specifically for any one program;并且不要忘记启动代码和库是“通用的”,不太可能专门针对任何一个程序进行优化; you can say that the best size for the heap's "allocated but not used" space is impossible to determine, but ranges from "maybe too small but it doesn't matter much" to "maybe too big but nobody cares".您可以说堆的“已分配但未使用”空间的最佳大小无法确定,但范围从“可能太小但无关紧要”到“可能太大但没人关心”。 Different compilers and/or libraries and/or operating systems make different decisions;不同的编译器和/或库和/或操作系统做出不同的决定; so the amount of "allocated but not used" space varies.因此“已分配但未使用”的空间量会有所不同。

Am I looking at the wrong indicator?我看错了指标吗?

I don't know (it depends on why you're looking at memory stats to begin with).我不知道(这取决于您开始查看内存统计信息的原因)。

On modern machines the total virtual address space may be 131072 GiB (where most is "not allocated"), so if you're worried that "allocated but not used" space is going to cause you to run out of "not allocated" space later then you're looking at the right indicator.在现代机器上,总虚拟地址空间可能是 131072 GiB(其中大部分是“未分配”),所以如果您担心“已分配但未使用”空间会导致您用完“未分配”空间稍后您将看到正确的指标。

Typically people care more about (some subset of) "allocated and actually used space" though.通常,人们更关心(某些子集)“分配和实际使用的空间”。

If you're worried about consuming too much actual RAM (eg worried about increasing the chance that swap space will be used by the OS, which could reduce performance of all software and not just yours) then you'd want to look at the "Real Memory Size";如果您担心消耗过多的实际 RAM(例如,担心会增加操作系统使用交换空间的机会,这可能会降低所有软件的性能,而不仅仅是您的软件),那么您需要查看“实际内存大小"; but I suspect that this includes shared memory (which would be used by many programs and not just your program).但我怀疑这包括共享内存(许多程序会使用它,而不仅仅是你的程序)。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM