ในขณะที่คนอื่นชี้ให้เห็นอย่างถูกต้องมันเป็นเรื่องยากที่จะจัดการกับหน่วยความจำจริงที่ใช้โดยกระบวนการสิ่งที่มีพื้นที่ที่ใช้ร่วมกันและไฟล์ mmap'ed และอะไรก็ตาม
หากคุณเป็นผู้ทดลองคุณสามารถเรียกใช้valgrind และเทือกเขา สิ่งนี้อาจจะค่อนข้างหนักสำหรับผู้ใช้ทั่วไป แต่คุณจะได้รับแนวคิดเกี่ยวกับพฤติกรรมความจำของแอปพลิเคชันเมื่อเวลาผ่านไป หากแอปพลิเคชัน malloc () เป็นสิ่งที่ต้องการจริงๆสิ่งนี้จะช่วยให้คุณแสดงการใช้หน่วยความจำแบบไดนามิกที่แท้จริงของกระบวนการ แต่การทดลองนี้สามารถ "วางยาพิษ" ได้
ในการทำให้เรื่องซับซ้อนลีนุกซ์อนุญาตให้คุณเขียนทับหน่วยความจำของคุณมากเกินไป เมื่อคุณใช้หน่วยความจำ malloc () แสดงว่าคุณตั้งใจจะใช้ความจำ แต่การจัดสรรจะไม่เกิดขึ้นจนกว่าคุณจะเขียนไบต์ลงในหน้าใหม่ของ "RAM" ที่จัดสรรของคุณ คุณสามารถพิสูจน์ได้ด้วยตัวเองโดยการเขียนและรันโปรแกรม C ตัวเล็ก ๆ เช่น:
// test.c
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>
int main() {
    void *p;
    sleep(5)
    p = malloc(16ULL*1024*1024*1024);
    printf("p = %p\n", p);
    sleep(30);
    return 0;
}
# Shell:
cc test.c -o test && ./test &
top -p $!
รันสิ่งนี้บนเครื่องที่มี RAM น้อยกว่า 16GB และ voila! คุณเพิ่งได้คะแนนจากหน่วยความจำ 16GB! (ไม่ไม่ได้จริงๆ)
โปรดสังเกตtopว่าคุณเห็น "VIRT" เป็น 16.004G แต่% MEM คือ 0.0
เรียกใช้อีกครั้งด้วย valgrind:
# Shell:
valgrind --tool=massif ./test &
sleep 36
ms_print massif.out.$! | head -n 30
และ massif บอกว่า "ผลรวมของ allocs () = 16GB" นั่นไม่น่าสนใจมาก
แต่ถ้าคุณใช้ในกระบวนการมีสติ :
# Shell:
rm test test.o
valgrind --tool=massif cc test.c -o test &
sleep 3
ms_print massif.out.$! | head -n 30
--------------------------------------------------------------------------------
Command:            cc test.c -o test
Massif arguments:   (none)
ms_print arguments: massif.out.23988
--------------------------------------------------------------------------------
    KB
77.33^                                                                       :
     |                                                                      #:
     |                                                                :@::@:#:
     |                                                           :::::@@::@:#:
     |                                                         @:: :::@@::@:#:
     |                                                     ::::@:: :::@@::@:#:
     |                                             ::@:::@:::::@:: :::@@::@:#:
     |                                            @::@:::@:::::@:: :::@@::@:#:
     |                                            @::@:::@:::::@:: :::@@::@:#:
     |                      :@@@@@@@@@@@@@@@@@@@@:@::@:::@:::::@:: :::@@::@:#:
     |                      :@@                  :@::@:::@:::::@:: :::@@::@:#:
     |                    :@:@@                  :@::@:::@:::::@:: :::@@::@:#:
     |                    :@:@@                  :@::@:::@:::::@:: :::@@::@:#:
     |                   :@@:@@                  :@::@:::@:::::@:: :::@@::@:#:
     |                   :@@:@@                  :@::@:::@:::::@:: :::@@::@:#:
     |              :@::::@@:@@                  :@::@:::@:::::@:: :::@@::@:#:
     |          :::::@::::@@:@@                  :@::@:::@:::::@:: :::@@::@:#:
     |        :::::::@::::@@:@@                  :@::@:::@:::::@:: :::@@::@:#:
     |       ::::::::@::::@@:@@                  :@::@:::@:::::@:: :::@@::@:#:
     |       ::::::::@::::@@:@@                  :@::@:::@:::::@:: :::@@::@:#:
   0 +----------------------------------------------------------------------->Mi
     0                                                                   1.140
และที่นี่เราเห็น (มากสังเกตุและมีความมั่นใจสูงมาก) ว่าคอมไพเลอร์จัดสรรฮีป 77KB
เหตุใดจึงต้องพยายามอย่างหนักเพื่อให้ได้รับการใช้งานฮีพเพียงอย่างเดียว เนื่องจากวัตถุที่ใช้ร่วมกันและส่วนข้อความทั้งหมดที่กระบวนการใช้ (ในตัวอย่างนี้คอมไพเลอร์) ไม่น่าสนใจอย่างมาก ค่าใช้จ่ายคงที่สำหรับกระบวนการ อันที่จริงการขอร้องกระบวนการต่อมาเกือบจะ "ฟรี"  
เปรียบเทียบและคอนทราสต์ต่อไปนี้ด้วย:
MMAP () ไฟล์ 1GB VMSize ของคุณจะเป็น 1 + GB แต่คุณจะใช้ขนาดชุดที่อยู่อาศัยจะเป็นเพียงบางส่วนของไฟล์ที่คุณได้รับการทำเพจใน และถ้าคุณ "อ่าน" ไฟล์ทั้งหมดจากนั้นเมื่อถึงจุดสิ้นสุดเคอร์เนลอาจเริ่มต้นเพจแล้ว (ซึ่งเป็นเรื่องง่ายที่จะทำเพราะเคอร์เนลรู้วิธีการ / ตำแหน่งที่จะเปลี่ยนหน้าเหล่านั้นได้อย่างถูกต้อง ) ไม่ว่าในกรณีใด VMSize หรือ RSS จะเป็นตัวบ่งชี้ที่ดีสำหรับการใช้งาน "หน่วยความจำ" ของคุณ คุณยังไม่ได้ malloc () 'ed อะไรเลย  
ในทางตรงกันข้าม Malloc () และแตะหน่วยความจำจำนวนมาก - จนกว่าหน่วยความจำของคุณจะถูกเปลี่ยนเป็นดิสก์ ดังนั้นหน่วยความจำที่จัดสรรของคุณจะเกิน RSS ของคุณแล้ว ที่นี่ VMSize ของคุณอาจเริ่มบอกบางสิ่งกับคุณ (กระบวนการของคุณเป็นเจ้าของหน่วยความจำมากกว่าสิ่งที่อยู่ใน RAM จริง) แต่ก็ยังคงยากที่จะแยกแยะความแตกต่างระหว่าง VM ซึ่งเป็นเพจที่ใช้ร่วมกันและ VM ที่เปลี่ยนข้อมูล  
นี่คือจุดที่ valgrind / massif ได้รับความสนใจ มันแสดงให้คุณเห็นถึงสิ่งที่คุณจัดสรรไว้โดยไม่เจตนา
               
              
htopผู้เขียนกับคำถามที่คล้ายกันหนึ่งคำถามที่ฉันมีในวันอื่น ... วิธีการคำนวณการใช้หน่วยความจำจาก / proc / meminfo (เช่น htop)