Linux 运行时虚拟内存的大小

Linux 运行时虚拟内存的大小,linux,Linux,我创建了一个应用程序,当我使用size进行检查时,其大小显示为 admin@pc:~/Desktop$ size u text data bss dec hex filename 1725 552 16 2293 8f5 u 在运行时使用ps-au检查时 admin@pc:~/Desktop$ ps -au USER PID %CPU %MEM VSZ RSS TTY ST

我创建了一个应用程序,当我使用
size
进行检查时,其大小显示为

  admin@pc:~/Desktop$ size u
  text     data     bss     dec     hex  filename  
  1725     552       16    2293     8f5   u
在运行时使用ps-au检查时

admin@pc:~/Desktop$ ps -au  
USER    PID    %CPU %MEM  VSZ    RSS TTY      STAT START   TIME COMMAND  
admin   16730  0.0  0.0   3876   448 pts/2    S+   15:48   0:00 ./u  
admin   16731  0.0  0.0   3876   252 pts/2    S+   15:48   0:00 ./u
  • 为什么它显示的虚拟内存大小与我们使用size命令看到的不同。i、 e为什么2293与VSZ(3876)不同,如
    ps-au
  • 由于虚拟内存的大小非常小,它可以累积在4k字节的单页帧(RAM/RSS)中。这意味着,由于2293字节小于4096字节,整个过程可以加载到单个帧中。那么,为什么RSS 448和252比2293或3876小
  • 为什么它显示的虚拟内存大小与我们使用size命令看到的不同。i、 为什么2293不同于ps-au看到的VSZ(3876)

    堆栈和堆不存储在二进制文件中,它们仅在运行时创建。这就是为什么二进制文件的
    文本
    数据
    bss
    部分的大小加起来不等于
    VSZ

    由于虚拟内存的大小非常小,它可以累积在4k字节的单页帧(RAM/RSS)中。这意味着,由于2293字节小于4096字节,整个过程可以加载到单个帧中。那么,为什么RSS 448和252比2293或3876小

    VSZ
    以1024字节为单位报告。换句话说,
    3876
    代表3969024字节

    为什么它显示的虚拟内存大小与我们使用size命令看到的不同。i、 为什么2293不同于ps-au看到的VSZ(3876)

    堆栈和堆不存储在二进制文件中,它们仅在运行时创建。这就是为什么二进制文件的
    文本
    数据
    bss
    部分的大小加起来不等于
    VSZ

    由于虚拟内存的大小非常小,它可以累积在4k字节的单页帧(RAM/RSS)中。这意味着,由于2293字节小于4096字节,整个过程可以加载到单个帧中。那么,为什么RSS 448和252比2293或3876小


    VSZ
    以1024字节为单位报告。换句话说,
    3876
    代表3969024字节。

    我确信
    u
    会加载一些共享库。这些增加了尺寸。使用
    ldd./u
    查看这些

    对于VSZ,该值以1kib(1024字节)为单位:

    进程的VSZ虚拟内存大小,单位为KiB(1024字节单位)

    (来源:ps(1)的Ubuntu手册页)

    虚拟大小包含进程所需的所有内存,也包括为进程保留但实际上未使用的页面


    RSS是当前内存中的内存量。两个进程实际上保留了相同数量的内存,但第二个进程实际上没有分配那么多内存(使用
    malloc(3)
    或类似的库或内核调用),或者它还没有加载所有共享库(它们是根据需要部分加载的)。

    我非常确定
    u
    加载了一些共享库。这些增加了尺寸。使用
    ldd./u
    查看这些

    对于VSZ,该值以1kib(1024字节)为单位:

    进程的VSZ虚拟内存大小,单位为KiB(1024字节单位)

    (来源:ps(1)的Ubuntu手册页)

    虚拟大小包含进程所需的所有内存,也包括为进程保留但实际上未使用的页面


    RSS是当前内存中的内存量。两个进程实际上保留了相同数量的内存,但第二个进程实际上没有分配那么多的内存(使用
    malloc(3)
    或类似的库或内核调用),或者它还没有加载所有共享库(它们是根据需要部分加载的)。

    使用
    pmap
    或者干脆使用
    cat/proc/$(pidof./u)/映射
    以了解正在运行的程序的虚拟地址空间
    /u
    !只是一个想法,因为这个问题更合适。使用
    pmap
    或简单地
    cat/proc/$(pidof./u)/maps
    来理解运行程序的虚拟地址空间
    /u
    !这只是一个想法,因为这个问题更合适。unix链接器在启动时加载所有共享库,而不是按需解析符号,请参见
    man ld.SO
    ld\u BIND\u NOW
    。应用程序可以使用
    dlopen()
    @MaximYegorushkin按需加载共享库:它们添加到
    size
    的输出中。进程启动后,您应该立即在
    VSZ
    中看到所有共享库代码的总和,但它们本身会根据需要分配内存,而且单个代码页不会映射到进程空间(=不在RSS中)。在./u进程程序中,我已包括stdio.h、unistd.h、string.h头文件。这是否意味着该进程将只加载与头文件关联的库文件(无论是动态库还是静态库),还是加载所有动态库和静态库,而不考虑包含的头文件?@EmbeddedProgrammer:这取决于您的操作系统以及它是如何执行这些操作的。
    ldd
    命令回答此问题。但ldd将仅显示共享库(即动态库)。但是静态库呢?unix链接器一开始就加载所有共享库,而是根据需要解析符号,请参见
    manld.so
    ld\u NOW
    。应用程序可以使用
    dlopen()
    @MaximYegorushkin按需加载共享库:它们添加到
    size
    的输出中。进程启动后,您应该立即在
    VSZ
    中看到所有共享库代码的总和,但它们本身会根据需要分配内存,而且单个代码页不会映射到进程空间(=不在RSS中)。在./u进程程序中,我已包括stdio.h、unistd.h、string.h头文件。这是否意味着进程将只加载与heade关联的库文件(无论是动态库还是静态库)