Làm thế nào tôi có thể tìm thấy rò rỉ bộ nhớ của một quá trình đang chạy?


19

Có cách nào, tôi có thể tìm thấy rò rỉ bộ nhớ của một quá trình đang chạy không? Tôi có thể sử dụng Valgrind để tìm rò rỉ bộ nhớ trước khi bắt đầu quá trình. Tôi có thể sử dụng GDB để gắn nó vào một quy trình đang chạy. Làm thế nào tôi có thể gỡ lỗi rò rỉ bộ nhớ của một quá trình đang chạy?


Valgrind rất hữu ích, tôi thậm chí sẽ gọi nó là trực quan.
dùng400344

Câu trả lời:


13

Đây là các bước gần như đảm bảo để tìm ra ai đang rò rỉ bộ nhớ:

  1. Tìm ra PID của quá trình gây rò rỉ bộ nhớ.

    ps -aux
  2. nắm bắt /proc/PID/smapsvà lưu vào một số tập tin như BeforeMemInc.txt.

  3. chờ cho đến khi bộ nhớ được tăng lên.
  4. chụp lại /proc/PID/smapsvà lưu nóafterMemInc.txt
  5. tìm sự khác biệt giữa thứ nhất smapsvà thứ 2 smaps, ví dụ với

    diff -u beforeMemInc.txt afterMemInc.txt

  6. ghi lại phạm vi địa chỉ nơi tăng bộ nhớ, ví dụ:

       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. sử dụng GDB để kết xuất bộ nhớ trong quá trình chạy hoặc lấy coredump bằng cách sử dụng gcore -o process

  8. Tôi đã sử dụng gdb trong quá trình chạy để kết xuất bộ nhớ vào một số tệp.

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
  9. Bây giờ, sử dụng stringslệnh hoặc hexdump -Cđể indump_outputfile.dump

    strings outputfile.dump
  10. Bạn nhận được dạng có thể đọc được nơi bạn có thể định vị các chuỗi đó vào mã nguồn của mình.

  11. Phân tích nguồn của bạn để tìm rò rỉ.


12

Tôi nghĩ memleax là chính xác những gì bạn muốn.

Nó gỡ lỗi rò rỉ bộ nhớ của một tiến trình đang chạy bằng cách đính kèm nó, mà không biên dịch lại chương trình hoặc khởi động lại tiến trình đích. Nó rất thuận tiện và phù hợp với môi trường sản xuất.

Nó hoạt động trên GNU / Linux và FreeBSD.

LƯU Ý: Tôi là tác giả, mọi đề xuất đều được hoan nghênh

== CHỈNH SỬA ==

Tôi viết một công cụ libleak khác , móc các hàm bộ nhớ của LD_PRELOAD.

Cũng không cần phải sửa đổi chương trình mục tiêu. Mặc dù bạn phải khởi động lại tiến trình với LD_PRELOAD, bạn có thể bật / tắt phát hiện trong khi chạy.

Có ít tác động hơn đến hiệu suất vì không có bẫy tín hiệu.

So với các công cụ tương tự (như mtrace), nó in toàn bộ ngăn xếp cuộc gọi tại điểm rò rỉ bộ nhớ đáng ngờ.


1
Tôi bảo đảm cho memleax là một công cụ rất hữu ích để theo dõi mọi rò rỉ rõ ràng. Các tóm tắt đầu ra có hiệu quả đáng ngạc nhiên . Gần như tôi sẽ viết chúng nếu tôi có khả năng xử lý để làm thủ công. Cảm ơn vì điều này
sehe


0

Tôi nghĩ rằng không cung cấp hỗ trợ cho giám sát phân bổ sau khi chương trình bắt đầu trực tiếp trong mã nguồn, bạn sẽ không gặp may. Đây là hai lý do tôi có thể nghĩ ra:

  • Trình kiểm tra heap khởi tạo khi chương trình bắt đầu. Một số cung cấp khả năng điều chỉnh thời gian chính xác, nhưng các biến môi trường bắt đầu chúng phải được đặt khi chương trình chạy. Điều này là do họ xem để đảm bảo mỗi phân bổ có một thỏa thuận tương ứng và họ sẽ bỏ lỡ một số khác.
  • Kiểm tra heap thường yêu cầu các đặc quyền nâng cao, hoặc hook, được cung cấp bởi hệ điều hành. Nếu các móc đó không được cung cấp tại thời điểm bắt đầu chương trình, trình kiểm tra heap không thể tận dụng chúng. Tôi không tin các hệ điều hành cung cấp các đặc quyền này sau khi chương trình đang được đề cập bắt đầu.

Tuy nhiên, nếu chương trình của bạn đang chạy bên trong một máy ảo, môi trường đó có thể cung cấp hỗ trợ cho việc phân bổ giám sát. Tôi biết Java có một số công cụ giám sát bộ sưu tập rác và phân bổ (như visualVM ) gắn với các chương trình hoặc máy ảo đang chạy.


0

IBM's Purify có lẽ là công cụ lâu đời nhất và tinh vi nhất trong tất cả. Nó sẽ đánh dấu số dòng trong mã gây rò rỉ bộ nhớ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.