วิธีการตรวจสอบการรั่วไหลของหน่วยความจำ?


16

ฉันดูเหมือนจะมีหน่วยความจำรั่วขนาดใหญ่ในระบบอูบุนตูปัจจุบันของฉัน

หลังจากรายงานข้อผิดพลาดหน่วยความจำ Eclipse แปลก ๆ ( /ubuntu/148998/eclipse-constant-different-out-of-memory-errors ) ฉันเริ่มได้รับข้อความแสดงข้อผิดพลาด 'หน่วยความจำไม่เพียงพอ' ในคอนโซลของฉันวันนี้ - ในขณะที่ ทำงานง่ายๆเช่นพิมพ์sudo -sหรือ -free -m

การพิมพ์ใน 'free -m' แสดงให้ฉันเห็นว่า RAM ของฉันเพิ่มขึ้นอย่างรวดเร็วจาก 700M เป็น 900M ได้อย่างไรและเติบโตขึ้นถึงขนาด 2000M ในไม่กี่วินาที (หลังจากเพิ่มหน่วยความจำด้วยecho 3 > /proc/sys/vm/drop_caches)

Eclipse ไม่ใช่สาเหตุฉันฆ่ากระบวนการโดยสิ้นเชิงและหน่วยความจำยังคงเพิ่มขึ้น มีวิธีใดที่จะตรวจสอบว่ามีรอยรั่วมาจากไหน? ฉันไม่สามารถอัปเดตระบบของฉันได้อีกต่อไปเนื่องจากapt-get updateล้มเหลว (อาจเป็นเพราะหน่วยความจำไม่เพียงพอ)

การใช้ Ubuntu 11.10


ฉันมีความสุขมากฉันไม่ได้บ้า ฉันมีปัญหาเดียวกันตั้งแต่อัปเกรดเป็น 13.10 แต่ฉันจำได้ด้วยการใช้ 11.10 คำถามคือ: คุณใช้ CrashPlan หรือไม่? ฉันดูเหมือนว่าจะแคบลงไปฉันไม่ทราบวิธีการแก้ไข ฉันลองปรับแต่งความจำแล้ว แต่มันไม่ทำงาน ฉันหวังว่ามันจะให้เบาะแสแก่คุณ
มือใหม่กึ่ง

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

คำตอบ:


9

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

memprof ทำงานได้โดยการโหลดไลบรารีล่วงหน้าเพื่อแทนที่ฟังก์ชั่นการจัดสรรหน่วยความจำของไลบรารี C และไม่ต้องการให้คุณคอมไพล์โปรแกรมของคุณใหม่

memprof

ที่มา: คู่มือ Ubuntu


11

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

คุณสามารถสร้างโฟลเดอร์ tmp ใหม่โดยใช้คำสั่งต่อไปนี้ คุณอาจต้องการเปลี่ยน/tmpเป็นระบบไฟล์อื่นที่มีพื้นที่เพียงพอ

TMPDIR=$(mktemp -d -t -p /tmp)

ขั้นตอนในการค้นหาหน่วยความจำรั่ว

  1. ค้นหา PID ของกระบวนการที่ทำให้หน่วยความจำรั่ว (คุณสามารถใช้เช่นhtopถ้ามี) และเก็บไว้ในตัวแปรที่เรียกว่าpid

    ps -aux
    
  2. ระบุว่า PID มีให้บริการในตัวแปรpidคุณสามารถจับภาพใช้หน่วยความจำโดยใช้และบันทึกลงในไฟล์บางอย่างเช่น/proc/$pid/smapsbeforeMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/beforeMemInc.txt
    
  3. รอสักครู่เพื่อให้ปริมาณการใช้หน่วยความจำเพิ่มขึ้น
  4. จับภาพ/proc/$pid/smapsอีกครั้งและบันทึกเป็นafterMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/afterMemInc.txt
    
  5. ค้นหาความแตกต่างระหว่างที่หนึ่งsmapsและที่smapsสองเช่นกับ

    diff -u $TMPDIR/beforeMemInc.txt $TMPDIR/afterMemInc.txt
    
  6. จดช่วงที่อยู่ที่หน่วยความจำเพิ่มขึ้นตัวอย่างเช่น

       beforeMemInc.txt            afterMemInc.txt
    ---------------------------------------------------
    2b3289290000-2b3289343000   2b3289290000-2b3289343000  #ADDRESS
    Shared_Clean:    0 kB       Shared_Clean:    0 kB          
    Shared_Dirty:    0 kB       Shared_Dirty:    0 kB
    Private_Clean:   0 kB       Private_Clean:   0 kB
    Private_Dirty:  28 kB       Private_Dirty:  36 kB  
    Referenced:     28 kB       Referenced:     36 kB
    Anonymous:      28 kB       Anonymous:      36 kB  #INCREASE MEM
    AnonHugePages:   0 kB       AnonHugePages:   0 kB
    Swap:            0 kB       Swap:            0 kB
    KernelPageSize:  4 kB       KernelPageSize:  4 kB
    MMUPageSize:     4 kB       MMUPageSize:     4 kB
    Locked:          0 kB       Locked:          0 kB
    VmFlags: rd wr mr mw me ac  VmFlags: rd wr mr mw me ac
    
  7. ใช้ GDB เพื่อถ่ายโอนข้อมูลหน่วยความจำในกระบวนการทำงานหรือรับ coredump โดยใช้

    gcore -o $TMPDIR/process $PID
    
  8. ฉันใช้ gdb ในกระบวนการทำงานเพื่อถ่ายโอนข้อมูลหน่วยความจำไปยังไฟล์บางไฟล์

    cd $TMPDIR
    gdb -p $pid
    dump memory memory.dump 0x2b3289290000 0x2b3289343000
    
  9. ตอนนี้ใช้stringsคำสั่งหรือhexdump -Cเพื่อพิมพ์memory.dump

    strings memory.dump
    

    จากนี้คุณจะได้รับข้อมูลที่อ่านได้ซึ่งช่วยให้คุณค้นหาสตริงเหล่านั้นในซอร์สโค้ดของคุณ

  10. วิเคราะห์แหล่งที่มาของคุณเพื่อค้นหาการรั่วไหล

ฉันอยู่ในคอนเทนเนอร์ Docker ได้รับข้อผิดพลาดการอนุญาตถูกปฏิเสธเมื่อทำงานcat /proc/2882/smaps > /tmp/before.txtในขั้นตอนที่ 2 ฉันทำอะไรผิด
Devy

8

เคล็ดลับ drop_cache จะไม่เพิ่มหน่วยความจำ แต่จะรีเซ็ตแคช ใช้คำสั่งpsหากคุณต้องการระบุกระบวนการที่ใช้หน่วยความจำมากขึ้น

ตัวอย่างเช่นในการตรวจสอบรายชื่อ 15 อันดับแรกของผู้ใช้หน่วยความจำภายใน

$ watch "ps --sort -rss -eo pid,pmem,rss,vsz,comm | head -16"
  PID %MEM   RSS    VSZ COMMAND
 2590 13.4 136892 825000 firefox
 1743 10.7 109020 300780 Xorg
 2067  8.5 86764 1118140 unity-2d-shell
 3307  4.1 42560 627780 unity-2d-spread
 2068  2.9 29904 617644 unity-2d-panel
 2092  2.5 25524 1291204 nautilus
 2457  1.9 20292 530276 gnome-terminal
 2351  1.9 20016 821488 unity-scope-vid
 2161  1.9 19476 531968 unity-panel-ser
 2034  1.7 18256 759716 gnome-settings-
 2074  1.5 16176 518016 nm-applet
 2273  1.5 15452 580416 unity-lens-vide
 2051  1.4 15112 524260 metacity
 2395  1.2 12836 407336 update-notifi

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

การจัดสรร Pmap:

$ ls -l /run/shm
total 272
-r-------- 1 ed      ed      67108904 Nov 29 18:17 pulse-shm-1884617860
-r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-2352897759
-r-------- 1 ed      ed      67108904 Nov 29 18:12 pulse-shm-3444873503
-r-------- 1 ed      ed      67108904 Nov 29 18:12 pulse-shm-3485341848
-r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-535843976
-r-------- 1 ed      ed      67108904 Nov 29 19:12 pulse-shm-789046959
-r-------- 1 ed      ed      67108904 Nov 29 18:38 pulse-shm-863909656

$ df /run/shm 
Filesystem     1K-blocks  Used Available Use% Mounted on
none              509332   272    509060   1% /run/shm

โปรดทราบว่าการจัดสรรที่สงวนไว้นั้นสูงกว่าหน้าจัดสรรจริง (df 'used')

การจัดสรรระบบ V:

$ ipcs -m 

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 294912     ed         700        122880     2          dest         
0x00000000 327681     ed         700        4823040    2          dest         
0x00000000 491522     ed         600        393216     2          dest         
0x00000000 589827     ed         700        4578120    2          dest         
0x00000000 425988     ed         700        27852      2          dest         
0x00000000 458757     ed         600        393216     2          dest         

แก้ไข : จำเป็นต้องส่งผ่าน--sort -rssเพื่อpsรับกระบวนการที่มีการใช้หน่วยความจำมากที่สุดมิฉะนั้นรายการกระบวนการจะเรียงลำดับตัวเลขที่เพิ่มขึ้นและให้กระบวนการที่มีการใช้หน่วยความจำน้อยที่สุด


5

ฉันมีเครื่องรุ่นเก่าที่ฉันใช้ซึ่งพ่นข้อความรั่วไหลของหน่วยความจำอย่างต่อเนื่อง:

root@:~# free -m
             total       used       free     shared    buffers     cached
Mem:          1898       1523        374        131         32        588
-/+ buffers/cache:        902        995
Swap:         1942        480       1462

สคริปต์ของฉัน:

sync; sudo echo 3 > /proc/sys/vm/drop_caches

ตั้งชื่อมัน cache.sh

root@~# ./cache.sh
root@~# free -m
             total       used       free     shared    buffers     cached
Mem:          1898       1106        791        126          1        207
-/+ buffers/cache:        897       1000
Swap:         1942        480       1462

คุณสามารถเห็นฉันลดลงเหลือ 374 MB วิ่งsync; sudo echo 3 > /proc/sys/vm/drop_cachesและได้รับ 417 MB กลับมา สามารถทำได้cronทุก ๆ 5 นาทีหรือเปิดเทอร์มินัลแล้วรันเมื่อคุณเห็นประสิทธิภาพการทำงานช้า ใช่ฉันต้องเพิ่มหน่วยความจำในเครื่อง ...


การจัดรูปแบบดูเหมือนจะเป็นปัญหา แต่ไม่แน่ใจว่าจะแก้ไขอย่างไร
Warpig

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

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

ขอบคุณมากเดวิด ... ฉันเห็นด้วยกับการล้าง / วางแคชผิดทั้งหมด ... แต่มีบางอย่างกำลังถูกวางสายและทำให้เครื่องค้าง / หยุดทำงาน ... งงงันกับสิ่งที่มันคิดว่าเป็นปัญหาของ Firefox ..
Warpig

3

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

memstat -w -p pid เป็นคำสั่งที่ดีที่จะใช้


1
ลิงก์ใช้งานไม่ได้ฉันคิดว่าอันนี้ดี
vladkras

1

ฉันมีปัญหาที่คล้ายกัน แต่ด้วยวิธีแก้ปัญหาที่แปลกมาก

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.