วิธีใช้คำสั่ง pmap บน Linux

เผยแพร่แล้ว: 2022-06-25
แล็ปท็อป Linux แสดง bash prompt
fatmawati achmad zaenuri/Shutterstock.com

การค้นหาว่ากระบวนการ Linux ใช้ RAM มากเพียงใดนั้นไม่ใช่เรื่องง่าย โดยเฉพาะอย่างยิ่งเมื่อจำเป็นต้องพิจารณาหน่วยความจำที่ใช้ร่วมกัน โชคดีที่คำสั่ง pmap ช่วยให้คุณเข้าใจทุกอย่างได้

การทำแผนที่หน่วยความจำ

บนระบบปฏิบัติการสมัยใหม่ แต่ละกระบวนการอาศัยอยู่ในพื้นที่หน่วยความจำหรือ พื้นที่จัดสรรที่จัดสรร ไว้ ขอบเขตของภูมิภาคที่จัดสรรจะไม่ถูกแมปโดยตรงกับที่อยู่ฮาร์ดแวร์จริง ระบบปฏิบัติการสร้างพื้นที่หน่วยความจำเสมือนสำหรับแต่ละกระบวนการและทำหน้าที่เป็นชั้นนามธรรมที่แมปหน่วยความจำเสมือนกับหน่วยความจำกายภาพ

เคอร์เนลรักษาตารางการแปลสำหรับแต่ละกระบวนการ และเข้าถึงได้โดย CPU เมื่อเคอร์เนลเปลี่ยนกระบวนการที่ทำงานบนคอร์ CPU เฉพาะ เคอร์เนลจะอัพเดตตารางการแปลที่เชื่อมโยงกระบวนการและคอร์ของ CPU เข้าด้วยกัน

ประโยชน์ของนามธรรม

มีประโยชน์กับโครงการนี้ การใช้หน่วยความจำค่อนข้างถูกห่อหุ้มและแซนด์บ็อกซ์สำหรับแต่ละกระบวนการใน userland กระบวนการเพียง "เห็น" หน่วยความจำในแง่ของที่อยู่หน่วยความจำเสมือน ซึ่งหมายความว่าสามารถทำงานได้เฉพาะกับหน่วยความจำที่ได้รับจากระบบปฏิบัติการเท่านั้น เว้นแต่จะมีสิทธิ์เข้าถึงหน่วยความจำที่ใช้ร่วมกันบางรายการก็ไม่ทราบหรือเข้าถึงหน่วยความจำที่จัดสรรให้กับกระบวนการอื่นไม่ได้

Swappiness บน Linux คืออะไร? (และวิธีการเปลี่ยนแปลง)
ที่เกี่ยวข้อง Swappiness บน Linux คืออะไร? (และวิธีการเปลี่ยนแปลง)

การแยกหน่วยความจำกายภาพที่ใช้ฮาร์ดแวร์เป็นที่อยู่หน่วยความจำเสมือนช่วยให้เคอร์เนลเปลี่ยนที่อยู่ทางกายภาพที่หน่วยความจำเสมือนบางส่วนถูกแมปไป สามารถสลับหน่วยความจำไปยังดิสก์โดยเปลี่ยนที่อยู่จริงที่ภูมิภาคของหน่วยความจำเสมือนชี้ไป นอกจากนี้ยังสามารถชะลอการให้หน่วยความจำกายภาพได้จนกว่าจะมีความต้องการจริง

ตราบใดที่คำขออ่านหรือเขียนหน่วยความจำได้รับบริการตามที่ร้องขอ เคอร์เนลสามารถเล่นปาหี่ตารางการแมปได้อย่างอิสระตามที่เห็นสมควร

RAM ตามความต้องการ

ตารางการทำแผนที่และแนวคิดของ “RAM ตามความต้องการ” เปิดโอกาสให้ มีหน่วยความจำที่ใช้ร่วมกัน ได้ เคอร์เนลจะพยายามหลีกเลี่ยงการโหลดสิ่งเดียวกันลงในหน่วยความจำมากกว่าหนึ่งครั้ง ตัวอย่างเช่น มันจะโหลดไลบรารีที่ใช้ร่วมกันลงในหน่วยความจำหนึ่งครั้ง และแมปกับกระบวนการต่าง ๆ ที่จำเป็นต้องใช้ แต่ละกระบวนการจะมีที่อยู่เฉพาะของตัวเองสำหรับไลบรารีที่ใช้ร่วมกัน แต่ทั้งหมดจะชี้ไปที่ตำแหน่งจริงเดียวกัน

ถ้าพื้นที่ที่ใช้ร่วมกันของหน่วยความจำสามารถเขียนได้ เคอร์เนลจะใช้รูปแบบที่เรียกว่า copy-on-write หากกระบวนการหนึ่งเขียนไปยังหน่วยความจำที่แบ่งใช้ และกระบวนการอื่นที่แชร์หน่วยความจำนั้นไม่ควรเห็นการเปลี่ยนแปลง สำเนาของหน่วยความจำที่แบ่งใช้จะถูกสร้างขึ้นที่จุดของคำขอเขียน

Beginner Geek: วิธีสร้างและใช้งาน Virtual Machines
Geek ที่เกี่ยวข้อง : วิธีสร้างและใช้เครื่องเสมือน

เคอร์เนลลินุกซ์ 2.6.32 ซึ่งเผยแพร่ในเดือนธันวาคม 2552 ทำให้ลินุกซ์มีคุณลักษณะที่เรียกว่า “การรวมเคอร์เนล SamePage” ซึ่งหมายความว่า Linux สามารถตรวจจับพื้นที่ที่เหมือนกันของข้อมูลในพื้นที่ที่อยู่ที่แตกต่างกัน ลองนึกภาพชุดของเครื่องเสมือนที่ทำงานบนคอมพิวเตอร์เครื่องเดียว และเครื่องเสมือนทั้งหมดใช้ระบบปฏิบัติการเดียวกัน การใช้แบบจำลองหน่วยความจำที่ใช้ร่วมกันและการคัดลอกเมื่อเขียน ค่าใช้จ่ายในคอมพิวเตอร์โฮสต์จะลดลงอย่างมาก

ทั้งหมดนี้ทำให้การจัดการหน่วยความจำใน Linux มีความซับซ้อนและเหมาะสมที่สุดเท่าที่จะทำได้ แต่ความซับซ้อนนั้นทำให้ยากต่อการดูกระบวนการและรู้ว่าการใช้หน่วยความจำจริงๆ คืออะไร

ยูทิลิตี้ pmap

เคอร์เนลเปิดเผยข้อมูลหลายอย่างที่มันทำกับ RAM ผ่านไฟล์หลอกสองไฟล์ในระบบไฟล์หลอกข้อมูลระบบ “/proc” มีสองไฟล์ต่อกระบวนการ ซึ่งตั้งชื่อตาม ID กระบวนการหรือ PID ของแต่ละกระบวนการ: “/proc/maps” และ “/proc//smaps”

เครื่องมือ pmap อ่านข้อมูลจากไฟล์เหล่านี้และแสดงผลลัพธ์ในหน้าต่างเทอร์มินัล จะเห็นได้ชัดว่าเราจำเป็นต้องระบุ PID ของกระบวนการที่เราสนใจทุกครั้งที่เราใช้ pmap

ค้นหา ID กระบวนการ

มีหลายวิธีในการค้นหา PID ของกระบวนการ นี่คือซอร์สโค้ดสำหรับโปรแกรมเล็กน้อยที่เราจะใช้ในตัวอย่างของเรา มันเขียนด้วยภาษา C ทั้งหมดที่ทำคือพิมพ์ข้อความไปที่หน้าต่างเทอร์มินัลและรอให้ผู้ใช้กดปุ่ม "Enter"

 #include <stdio.h>

int main(int argc, ถ่าน *argv[])
{
  printf("โปรแกรมทดสอบ How-To Geek");
  getc(stdin);
} // จบ main

โปรแกรมถูกคอมไพล์ไปยังไฟล์เรียกทำงาน pm โดยใช้คอมไพเลอร์ gcc :

 gcc -o pm pm.c 

รวบรวมโปรแกรมตัวอย่าง

เนื่องจากโปรแกรมจะรอให้ผู้ใช้กด Enter โปรแกรมจะทำงานต่อไปตราบเท่าที่เราต้องการ

 ./pm 

การรันโปรแกรมตัวอย่าง

โปรแกรมจะเปิดขึ้น พิมพ์ข้อความ และรอการกดแป้นพิมพ์ ตอนนี้เราสามารถค้นหา PID ของมันได้แล้ว คำสั่ง ps แสดงรายการกระบวนการที่ทำงานอยู่ ตัวเลือก -e (แสดงกระบวนการทั้งหมด) ทำให้ ps แสดงรายการทุกกระบวนการ เราจะไพพ์เอาต์พุตผ่าน grep และกรองรายการที่มี “pm” อยู่ในชื่อ

 ps -e | grep pm 

ค้นหา ID กระบวนการด้วย grep

รายการนี้จะแสดงรายการทั้งหมดที่มี “pm” ที่ใดก็ได้ในชื่อ

เราสามารถเจาะจงมากขึ้นโดยใช้คำสั่ง pidof เราให้ชื่อของกระบวนการที่เราสนใจในบรรทัดคำสั่ง pidof และพยายามค้นหารายการที่ตรงกัน หากพบการจับคู่ pidof จะพิมพ์ PID ของกระบวนการจับคู่

 pidof pm 

ใช้ pidof เพื่อค้นหา ID กระบวนการ

วิธี pidof จะเรียบร้อยกว่าเมื่อคุณรู้ชื่อของกระบวนการ แต่วิธี ps จะทำงานแม้ว่าจะรู้เพียงบางส่วนของชื่อกระบวนการก็ตาม

ใช้ pmap

เมื่อโปรแกรมทดสอบของเราทำงาน และเมื่อเราระบุ PID แล้ว เราก็สามารถใช้ pmap ได้ดังนี้:

 pmap 40919 

การรัน pmap บนโปรแกรมตัวอย่าง

การแมปหน่วยความจำสำหรับกระบวนการแสดงไว้สำหรับเรา

เอาต์พุต pmap มาตรฐาน

นี่คือผลลัพธ์ทั้งหมดจากคำสั่ง:

 40919: ./pm
000056059f06c000 4K r ---- pm
000056059f06d000 4K rx-- pm
000056059f06e000 4K r ---- pm
000056059f06f000 4K r ---- pm
000056059f070000 4K rw--- pm
000056059fc39000 132K rw--- [ อานนท์ ]
00007f97a3edb000 8K rw--- [ อานนท์ ]
00007f97a3edd000 160K r---- libc.so.6
00007f97a3f05000 1616K rx-- libc.so.6
00007f97a4099000 352K r---- libc.so.6
00007f97a40f1000 4K ----- libc.so.6
00007f97a40f2000 16K r---- libc.so.6
00007f97a40f6000 8K rw--- libc.so.6
00007f97a40f8000 60K rw--- [ อานนท์ ]
00007f97a4116000 4K r---- ld-linux-x86-64.so.2
00007f97a4117000 160K rx-- ld-linux-x86-64.so.2
00007f97a413f000 40K r---- ld-linux-x86-64.so.2
00007f97a4149000 8K r---- ld-linux-x86-64.so.2
00007f97a414b000 8K rw--- ld-linux-x86-64.so.2
00007ffca0e7e000 132K rw--- [ กอง ]
0007ffca0fe1000 16K r---- [ อานนท์ ]
00007ffca0fe5000 8K rx-- [ อานนท์ ]
ffffffffff6000000 4K --x-- [ นาน ]
รวม 2756K

บรรทัดแรกคือชื่อกระบวนการและ PID บรรทัดอื่นแต่ละบรรทัดแสดงที่อยู่หน่วยความจำที่แมป และจำนวนหน่วยความจำที่ที่อยู่นั้น แสดงเป็นกิโลไบต์ อักขระห้าตัวถัดไปของแต่ละบรรทัดเรียกว่าการ อนุญาตหน่วยความจำเสมือน สิทธิ์ที่ถูกต้องคือ:

  • r : หน่วยความจำที่แมปสามารถอ่านได้โดยกระบวนการ
  • w : หน่วยความจำที่แมปสามารถเขียนได้โดยกระบวนการ
  • x : กระบวนการสามารถดำเนินการคำสั่งใด ๆ ที่มีอยู่ในหน่วยความจำที่แมป
  • s : หน่วยความจำที่แมปถูกแชร์ และการเปลี่ยนแปลงที่ทำกับหน่วยความจำที่แชร์นั้นสามารถมองเห็นได้ในทุกกระบวนการที่แชร์หน่วยความจำ
  • R : ไม่มีการสำรองพื้นที่สว็อปสำหรับหน่วยความจำที่แมปนี้

ข้อมูลสุดท้ายในแต่ละบรรทัดคือชื่อของแหล่งที่มาของการทำแผนที่ ซึ่งอาจเป็นชื่อกระบวนการ ชื่อไลบรารี หรือชื่อระบบ เช่น สแต็กหรือฮีป

จอแสดงผลแบบขยาย

ตัวเลือก -x (ขยาย) ให้คอลัมน์พิเศษสองคอลัมน์

 pmap -x 40919 

การใช้ตัวเลือกขยาย -X กับ pmap

คอลัมน์จะได้รับชื่อ เราได้เห็นคอลัมน์ "Address", "Kbytes", "Mode" และ "Mapping" แล้ว คอลัมน์ใหม่นี้เรียกว่า "RSS" และ "Dirty"

pmap ขยายเอาท์พุต

นี่คือผลลัพธ์ที่สมบูรณ์:

 40919: ./pm
ที่อยู่ Kbytes RSS Dirty Mode Mapping
000056059f06c000 4 4 0 r ---- pm
000056059f06d000 4 4 0 rx-- pm
000056059f06e000 4 4 0 r ---- pm
000056059f06f000 4 4 4 r ---- pm
000056059f070000 4 4 4 rw--- pm
000056059fc39000 132 4 4 rw--- [ อานนท์ ]
00007f97a3edb000 8 4 4 rw--- [ อานนท์ ]
00007f97a3edd000 160 160 0 r ---- libc.so.6
00007f97a3f05000 1616 788 0 rx-- libc.so.6
00007f97a4099000 352 64 0 r ---- libc.so.6
00007f97a40f1000 4 0 0 ----- libc.so.6
00007f97a40f2000 16 16 16 r ---- libc.so.6
00007f97a40f6000 8 8 8 rw--- libc.so.6
00007f97a40f8000 60 28 28 rw--- [ อานนท์ ]
00007f97a4116000 4 4 0 r ---- ld-linux-x86-64.so.2
00007f97a4117000 160 160 0 rx-- ld-linux-x86-64.so.2
00007f97a413f000 40 40 0 ​​r ---- ld-linux-x86-64.so.2
00007f97a4149000 8 8 8 r ---- ld-linux-x86-64.so.2
00007f97a414b000 8 8 8 rw--- ld-linux-x86-64.so.2
00007ffca0e7e000 132 12 12 rw--- [ กอง ]
00007ffca0fe1000 16 0 0 r---- [ อานนท์ ]
00007ffca0fe5000 8 4 0 rx-- [ อานนท์ ]
ffffffffff600000 4 0 0 --x-- [ อานนท์ ]
------ ------- ------- ------- 
รวม kB 2756 1328 96
  • RSS : นี่คือ ขนาดของชุดที่อยู่อาศัย นั่นคือจำนวนหน่วยความจำที่อยู่ใน RAM และไม่มีการสลับออก
  • สกปรก : หน่วยความจำ "สกปรก" เปลี่ยนไปตั้งแต่เริ่มกระบวนการและการทำแผนที่

แสดงให้ฉันเห็นทุกอย่าง

-X (มากกว่าแบบขยาย) เพิ่มคอลัมน์เพิ่มเติมให้กับผลลัพธ์ สังเกตตัวพิมพ์ใหญ่ "X" ตัวเลือกอื่นที่เรียกว่า -XX (มากกว่า -X ) จะแสดงให้คุณเห็นทุกสิ่ง pmap สามารถรับได้จากเคอร์เนล เนื่องจาก -X เป็นสับเซตของ -XX เราจะอธิบายผลลัพธ์จาก -XX

 pmap -XX 40919 

การใช้ -XX แสดงตัวเลือกทุกอย่างด้วย pmap

เอาต์พุตล้อมรอบอย่างน่ากลัวในหน้าต่างเทอร์มินัลและไม่สามารถอ่านได้จริง นี่คือผลลัพธ์แบบเต็ม:

 40919: ./pm
         ที่อยู่ Perm Offset Device ขนาดไอโหนด KernelPageSize MMUPageSize Rss Pss Shared_Clean Shared_Dirty Private_Clean Private_Dirty อ้างอิง ไม่ระบุชื่อ LazyFree AnonHugePages ShmemPmdMapped FilePmdMapped Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked THPelig
    56059f06c000 r--p 00000000 08:03 393304 4 4 4 4 4 0 0 4 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 rd mr mw me dw sd pm
    56059f06d000 r-xp 00001000 08:03 393304 4 4 4 4 4 0 0 4 0 4 0 0 0 0 0 0 0 0 0 0 0 0 rd อดีต คุณ mw ฉัน dw sd pm
    56059f06e000 r--p 00002000 08:03 393304 4 4 4 4 4 0 0 4 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 rd mr mw me dw sd pm
    56059f06f000 r--p 00002000 08:03 393304 4 4 4 4 4 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 rd mr mw me dw ac sd pm
    56059f070000 rw-p 00003000 08:03 393304 4 4 4 4 4 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 rd wr mr mw ฉัน dw ac sd pm
    56059fc39000 rw-p 00000000 00:00 0 132 4 4 4 4 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 rd wr mr mw ฉัน ac sd [heap]
    7f97a3edb000 rw-p 00000000 00:00 0 8 4 4 4 4 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 rd wr นาย mw ฉัน ac sd 
    7f97a3edd000 r--p 00000000 08:03 264328 160 4 4 160 4 160 0 0 160 0 0 0 0 0 0 0 0 0 0 0 0 rd mr mw ฉัน sd libc.so.6
    7f97a3f05000 r-xp 00028000 08:03 264328 1616 4 4 788 32 788 0 0 0 788 0 0 0 0 0 0 0 0 0 0 0 rd อดีต คุณ mw ฉัน sd libc.so.6
    7f97a4099000 r--p 001bc000 08:03 264328 352 4 4 64 1 64 0 0 0 64 0 0 0 0 0 0 0 0 0 0 0 0 rd mr mw ฉัน sd libc.so.6
    7f97a40f1000 ---p 00214000 08:03 264328 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 mr mw ฉัน sd libc.so.6
    7f97a40f2000 r--p 00214000 08:03 264328 16 4 4 16 16 0 0 16 16 16 0 0 0 0 0 0 0 0 0 0 0 rd นาย mw ฉัน ac sd libc.so.6
    7f97a40f6000 rw-p 00218000 08:03 264328 8 4 4 8 8 0 0 0 8 8 8 0 0 0 0 0 0 0 0 0 0 0 rd wr mr mw me ac sd libc.so.6
    7f97a40f8000 rw-p 00000000 00:00 0 60 4 4 28 28 0 0 0 28 28 28 0 0 0 0 0 0 0 0 0 0 0 rd wr นาย mw ฉัน ac sd 
    7f97a4116000 r--p 00000000 08:03 264305 4 4 4 4 0 4 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 rd mr mw ฉัน dw sd ld-linux-x86-64.so.2
    7f97a4117000 r-xp 00001000 08:03 264305 160 4 4 160 11 160 0 0 160 0 0 0 0 0 0 0 0 0 0 0 0 rd อดีต คุณ mw ฉัน dw sd ld-linux-x86-64.so.2
    7f97a413f000 r--p 00029000 08:03 264305 40 4 4 40 1 40 0 ​​0 40 0 ​​0 0 0 0 0 0 0 0 0 0 0 0 rd mr mw ฉัน dw sd ld-linux-x86-64.so.2
    7f97a4149000 r--p 00032000 08:03 264305 8 4 4 8 8 0 0 0 8 8 8 0 0 0 0 0 0 0 0 0 0 0 rd mr mw ฉัน dw ac sd ld-linux-x86-64.so.2
    7f97a414b000 rw-p 00034000 08:03 264305 8 4 4 8 8 0 0 0 8 8 8 0 0 0 0 0 0 0 0 0 0 0 rd wr mr mw ฉัน dw ac sd ld-linux-x86-64.so.2
    7ffca0e7e000 rw-p 00000000 00:00 0 132 4 4 12 12 0 0 0 12 12 12 0 0 0 0 0 0 0 0 0 0 0 rd wr mr mw me gd ac [stack]
    7ffca0fe1000 r--p 00000000 00:00 0 16 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rd mr pf io de dd sd [vvar]
    7ffca0fe5000 r-xp 00000000 00:00 0 8 4 4 0 4 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 rd อดีต mr mw ฉัน de sd [vdso]
ffffffffff600000 --xp 00000000 00:00 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 อดีต [vsyscall]
                                             ==== ============== ========== ==== === ============ == ========== ============= ============ ========== ==== ===== ======== ============= ============= ========== === ============== =================== ======= ====== = ========== 
                                             2756 92 92 1328 157 1220 0 12 96 1328 96 0 0 0 0 0 0 0 0 0 0 0 KB 

มีข้อมูลมากมายที่นี่ นี่คือสิ่งที่คอลัมน์ถือ:

  • ที่อยู่ : ที่อยู่เริ่มต้นของการทำแผนที่นี้ สิ่งนี้ใช้การกำหนดที่อยู่หน่วยความจำเสมือน
  • Perm : การอนุญาตของหน่วยความจำ
  • ออฟเซ็ ต : หากหน่วยความจำเป็นแบบไฟล์ ออฟเซ็ตของการแมปนี้ภายในไฟล์
  • อุปกรณ์ : หมายเลขอุปกรณ์ Linux ที่ระบุเป็นตัวเลขหลักและรอง คุณสามารถดูหมายเลขอุปกรณ์บนคอมพิวเตอร์ของคุณได้โดยเรียกใช้คำสั่ง lsblk
  • Inode : ไอโหนดของไฟล์ที่เชื่อมโยงอยู่ ตัวอย่างเช่น ในตัวอย่างของเรา นี่อาจเป็นไอโหนดที่เก็บข้อมูลเกี่ยวกับโปรแกรม pm
  • ขนาด : ขนาดของพื้นที่ที่แมปหน่วยความจำ
  • KernelPageSize : ขนาดหน้าที่เคอร์เนลใช้
  • MMUPageSize : ขนาดหน้าที่ใช้โดยหน่วยจัดการหน่วยความจำ
  • Rss : นี่คือ ขนาดชุดที่อยู่อาศัย นั่นคือจำนวนหน่วยความจำที่อยู่ใน RAM และไม่มีการสลับออก
  • Pss : นี่คือ ขนาดการแบ่งปันตามสัดส่วน นี่คือขนาดที่ใช้ร่วมกันส่วนตัวที่เพิ่มลงใน (ขนาดที่แชร์หารด้วยจำนวนการแชร์)
  • Shared_Clean : จำนวนหน่วยความจำที่แบ่งใช้กับกระบวนการอื่นที่ ไม่ได้ เปลี่ยนแปลงตั้งแต่สร้างการแมป โปรดทราบว่าแม้ว่าหน่วยความจำจะแชร์ได้ แต่หากไม่ได้แชร์หน่วยความจำจริงจะยังถือเป็นหน่วยความจำส่วนตัว
  • Shared_Dirty : จำนวนหน่วยความจำที่แชร์กับกระบวนการอื่นที่ มี การเปลี่ยนแปลงตั้งแต่สร้างการแมป
  • Private_Clean : จำนวนหน่วยความจำส่วนตัว—ไม่ได้แชร์กับกระบวนการอื่น—ซึ่ง ไม่มี การเปลี่ยนแปลงตั้งแต่สร้างการแมป
  • Private_Dirty : จำนวนหน่วยความจำส่วนตัวที่ มี การเปลี่ยนแปลงตั้งแต่สร้างการแมป
  • อ้างอิง : จำนวนหน่วยความจำที่ทำเครื่องหมายว่าอ้างอิงหรือเข้าถึงในปัจจุบัน
  • Anonymous : หน่วยความจำที่ไม่มีอุปกรณ์ให้สลับไปใช้ นั่นคือมันไม่ได้สำรองไฟล์
  • LazyFree : เพจที่ถูกตั้งค่าสถานะเป็น MADV_FREE หน้าเหล่านี้ถูกทำเครื่องหมายว่าว่างและเรียกคืนได้ แม้ว่าหน้าเหล่านี้อาจมีการเปลี่ยนแปลงที่ไม่ได้เขียนเป็นลายลักษณ์อักษรก็ตาม อย่างไรก็ตาม หากการเปลี่ยนแปลงที่ตามมาเกิดขึ้นหลังจากตั้งค่า MADV_FREE ในการแมปหน่วยความจำ แฟ MADV_FREE จะถูกลบออก และเพจจะไม่ถูกเรียกคืนจนกว่าจะมีการเขียนการเปลี่ยนแปลง
  • AnonHugePages : เป็นเพจหน่วยความจำ “ขนาดใหญ่” ที่ไม่ได้สำรองไฟล์ไว้ (ขนาดใหญ่กว่า 4 KB)
  • ShmemPmdMapped : หน่วยความจำที่ใช้ร่วมกันที่เกี่ยวข้องกับเพจขนาดใหญ่ ระบบไฟล์เหล่านี้อาจใช้โดยระบบไฟล์ที่อยู่ในหน่วยความจำทั้งหมด
  • FilePmdMapped : Page Middle Directory เป็นหนึ่งในรูปแบบการเพจที่มีให้สำหรับเคอร์เนล นี่คือจำนวนหน้าที่สำรองไฟล์ซึ่งชี้ไปที่รายการ PMD
  • Shared_Hugetlb : Translation Lookaside Tables หรือ TLBs เป็นแคชหน่วยความจำที่ใช้ในการปรับเวลาที่ใช้ในการเข้าถึงตำแหน่งหน่วยความจำ userspace ให้เหมาะสม ตัวเลขนี้คือจำนวน RAM ที่ใช้ใน TLB ที่เชื่อมโยงกับเพจหน่วยความจำขนาดใหญ่ที่ใช้ร่วมกัน
  • Private_Hugetlb : ตัวเลขนี้คือจำนวน RAM ที่ใช้ใน TLB ที่เชื่อมโยงกับหน้าหน่วยความจำส่วนตัวขนาดใหญ่
  • Swap : จำนวนสวอปที่ใช้
  • SwapPss : ขนาดหุ้นตามสัดส่วนการสวอป นี่คือจำนวนสวอปที่ประกอบด้วยเพจหน่วยความจำส่วนตัวที่สลับที่เพิ่มไปยัง (ขนาดที่แบ่งใช้หารด้วยจำนวนการแชร์)
  • ล็อค : สามารถล็อคการแมปหน่วยความจำเพื่อป้องกันไม่ให้ระบบปฏิบัติการเพจออกจากหน่วยความจำฮีปหรือหน่วยความจำนอกฮีป
  • THมีสิทธิ์ : นี่คือแฟล็กที่ระบุว่าการแมปมีสิทธิ์ในการจัดสรร เพจขนาดใหญ่ที่โปร่งใส หรือไม่ 1 หมายถึง จริง 0 หมายถึง เท็จ เพจขนาดใหญ่แบบโปร่งใสคือระบบจัดการหน่วยความจำที่ช่วยลดโอเวอร์เฮดของการค้นหาเพจ TLB บนคอมพิวเตอร์ที่มี RAM จำนวนมาก
  • VmFlags : ดูรายการแฟล็กด้านล่าง
  • การทำแผนที่ : ชื่อของแหล่งที่มาของการทำแผนที่ ซึ่งอาจเป็นชื่อกระบวนการ ชื่อไลบรารี หรือชื่อระบบ เช่น สแต็กหรือฮีป

VmFlags—แฟล็กหน่วยความจำเสมือน—จะเป็นชุดย่อยของรายการต่อไปนี้

  • rd : อ่านได้
  • wr : เขียนได้.
  • ตัวอย่าง : ปฏิบัติการได้
  • sh : แชร์
  • นาย : เมย์อ่านะ
  • mw : อาจเขียน.
  • ฉัน : อาจประหารชีวิต
  • ms : อาจแบ่งปัน.
  • gd : ส่วนกองโตขึ้น
  • pf : ช่วงหมายเลขเฟรมหน้าล้วน หมายเลขเฟรมหน้าคือรายการของหน้าหน่วยความจำกายภาพ
  • dw : ปิดการใช้งานเขียนไปยังไฟล์ที่แมป
  • แท้จริง : เพจถูกล็อคในหน่วยความจำ
  • io : พื้นที่ I/O ที่แมปหน่วยความจำ
  • sr : ให้อ่านคำแนะนำตามลำดับ (โดย madvise() )
  • rr : สุ่มอ่านคำแนะนำที่ให้ไว้
  • dc : อย่าคัดลอกขอบเขตหน่วยความจำนี้หากกระบวนการถูกแยก
  • de : อย่าขยายขอบเขตหน่วยความจำนี้ในการทำการแมปใหม่
  • ac : พื้นที่รับผิดชอบ
  • nr : พื้นที่สว็อปไม่ได้สงวนไว้สำหรับพื้นที่นั้น
  • ht : Area ใช้หน้า TLB ขนาดใหญ่
  • sf : ความผิดพลาดของเพจแบบซิงโครนัส
  • ar : แฟล็กเฉพาะสถาปัตยกรรม
  • wf : เช็ดพื้นที่หน่วยความจำนี้หากกระบวนการถูกแยก
  • dd : ไม่รวมขอบเขตหน่วยความจำนี้ใน core dumps
  • sd : ธงสกปรกนุ่ม
  • มม. : พื้นที่แผนที่ผสม
  • hg : หน้าใหญ่แนะนำแฟล็ก
  • nh : ไม่มีเพจขนาดใหญ่แนะนำแฟล็ก
  • mg : แฟล็กคำแนะนำที่ผสานได้
  • bt : ARM64 หน้าป้องกันความไม่เสถียรของอุณหภูมิอคติ
  • mt : เปิดใช้งานแท็กส่วนขยายการติดแท็กหน่วยความจำ ARM64
  • um : Userfaultfd ไม่มีการติดตาม
  • uw : การติดตาม Userfaultfd wr-protect

การจัดการหน่วยความจำมีความซับซ้อน

และการทำงานย้อนกลับจากตารางข้อมูลเพื่อทำความเข้าใจกับสิ่งที่เกิดขึ้นจริงนั้นยาก แต่อย่างน้อย pmap จะให้ภาพรวมแก่คุณ เพื่อให้คุณมีโอกาสที่ดีที่สุดในการค้นหาสิ่งที่คุณต้องรู้

เป็นเรื่องที่น่าสนใจที่จะสังเกตว่าโปรแกรมตัวอย่างของเราคอมไพล์เป็นไฟล์ปฏิบัติการไบนารีขนาด 16 KB แต่ก็ยังใช้ (หรือแชร์) หน่วยความจำบางส่วน 2756 KB เกือบทั้งหมดเนื่องจากไลบรารีรันไทม์

เคล็ดลับสุดท้ายที่เรียบร้อยอย่างหนึ่งคือ คุณสามารถใช้ pmap และคำสั่ง pidof ร่วมกัน โดยรวมการดำเนินการในการค้นหา PID ของกระบวนการและส่งผ่านไปยัง pmap เป็นคำสั่งเดียว:

 pmap $(pidof pm)