2009-05-22 42 views
24

Tôi đã found the following question, nhưng tôi đã tự hỏi nếu có một cách nhanh hơn và bẩn thỉu hơn để lấy ước tính số bộ nhớ mà trình thông dịch python hiện đang sử dụng cho tập lệnh của tôi không dựa vào các thư viện bên ngoài.Python tương đương với memory_get_usage() của PHP?

Tôi đến từ PHP và được sử dụng để sử dụng memory_get_usage()memory_get_peak_usage() rất nhiều cho mục đích này và tôi đã hy vọng tìm thấy một tương đương.

Trả lời

31

Một giải pháp đơn giản cho Linux và các hệ thống khác với /proc/self/status là đoạn mã sau, mà tôi sử dụng trong một dự án của tôi:

def memory_usage(): 
    """Memory usage of the current process in kilobytes.""" 
    status = None 
    result = {'peak': 0, 'rss': 0} 
    try: 
     # This will only work on systems with a /proc file system 
     # (like Linux). 
     status = open('/proc/self/status') 
     for line in status: 
      parts = line.split() 
      key = parts[0][2:-1].lower() 
      if key in result: 
       result[key] = int(parts[1]) 
    finally: 
     if status is not None: 
      status.close() 
    return result 

Nó trả về kích thước bộ nhớ thường trú hiện tại và đỉnh (đó có lẽ là những gì mọi người có ý nghĩa khi họ nói về bao nhiêu RAM một ứng dụng đang sử dụng). Thật dễ dàng để mở rộng nó để lấy các thông tin khác từ tệp /proc/self/status.

Đối với người hiếu: toàn bộ sản lượng cat /proc/self/status trông như thế này:

% cat /proc/self/status 
Name: cat 
State: R (running) 
Tgid: 4145 
Pid: 4145 
PPid: 4103 
TracerPid:  0 
Uid: 1000 1000 1000 1000 
Gid: 1000 1000 1000 1000 
FDSize: 32 
Groups: 20 24 25 29 40 44 46 100 1000 
VmPeak:  3580 kB 
VmSize:  3580 kB 
VmLck:   0 kB 
VmHWM:  472 kB 
VmRSS:  472 kB 
VmData:  160 kB 
VmStk:  84 kB 
VmExe:  44 kB 
VmLib:  1496 kB 
VmPTE:  16 kB 
Threads:  1 
SigQ: 0/16382 
SigPnd: 0000000000000000 
ShdPnd: 0000000000000000 
SigBlk: 0000000000000000 
SigIgn: 0000000000000000 
SigCgt: 0000000000000000 
CapInh: 0000000000000000 
CapPrm: 0000000000000000 
CapEff: 0000000000000000 
CapBnd: ffffffffffffffff 
Cpus_allowed: 03 
Cpus_allowed_list:  0-1 
Mems_allowed: 1 
Mems_allowed_list:  0 
voluntary_ctxt_switches:  0 
nonvoluntary_ctxt_switches:  0 
+2

là đỉnh/cư trú bằng kb hoặc byte? – Shabbyrobe

+1

Câu hỏi hay - tính bằng kilobyte, tôi đã thêm thông tin đó vào câu trả lời gốc. –

+0

Thanks heaps cho câu trả lời tuyệt vời. Là một sang một bên, bạn sẽ có bất kỳ ý tưởng tại sao đỉnh cao kết thúc lên trên 80mb (!!!) nếu tôi đẻ trứng một loạt các chủ đề, mặc dù cư dân vẫn tương đối thấp? Ngoài ra, bạn có bất kỳ manh mối nào về cách thực hiện điều này trên Win32 không? – Shabbyrobe

17

Bạn cũng có thể sử dụng chức năng getrusage() từ các module thư viện chuẩn resource. Đối tượng thu được có thuộc tính ru_maxrss, mang đến cho tổng số sử dụng bộ nhớ cho quá trình gọi điện thoại:

>>> import resource 
>>> resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
2656 

các Python docs không rõ ràng về những gì các đơn vị là chính xác, nhưng Mac OS X man page cho getrusage(2) mô tả các đơn vị như kilobyte.

Trang người dùng Linux không rõ ràng, nhưng dường như nó tương đương với thông tin /proc/self/status (tức là kilobyte) được mô tả trong câu trả lời được chấp nhận. Đối với quá trình tương tự như trên, chạy trên Linux, các chức năng được liệt kê trong câu trả lời chấp nhận cho:

>>> memory_usage()          
{'peak': 6392, 'rss': 2656} 

này có thể không được khá dễ dàng để sử dụng như một giải pháp /proc/self/status, nhưng nó là thư viện chuẩn, vì vậy (được cung cấp các đơn vị là tiêu chuẩn) nó phải là nền tảng chéo và có thể sử dụng trên các hệ thống thiếu /proc/ (ví dụ: Mac OS X và các Unix khác, có thể là Windows).

Ngoài ra, chức năng getrusage() cũng có thể được cấp resource.RUSAGE_CHILDREN để sử dụng cho quy trình con và (trên một số hệ thống) resource.RUSAGE_BOTH để sử dụng toàn bộ (tự và con).

Điều này sẽ bao gồm trường hợp memory_get_usage(), nhưng không bao gồm mức sử dụng tối đa. Tôi không chắc liệu có bất kỳ chức năng nào khác từ mô-đun resource có thể cung cấp mức sử dụng cao nhất hay không.

+0

OSX của tôi (sư tử) cho biết: '35819520' trên một tiến trình tôi đang chạy mà tôi chắc chắn là '35MB' thay vì' 35GB', do đó, nó sẽ có vẻ là byte. :) –

+2

Trên máy tính Ubuntu 11.10 của tôi, tôi nhận được resource.getrusage() là một giá trị gần với giá trị đỉnh của memory_usage() chứ không phải là rss. Bạn có chắc chắn rằng ru_maxrss đề cập đến việc sử dụng bộ nhớ hiện tại và không sử dụng bộ nhớ cao điểm? – Phani

+1

@Phani Dường như nó cũng rất cao với tôi. Thông tin thêm về ru_maxrss trong câu trả lời này: http://stackoverflow.com/a/12050966/67184 –

10

Quy tắc trả lời được chấp nhận, nhưng có thể dễ dàng hơn (và di động hơn) để sử dụng psutil. Nó làm như vậy và nhiều hơn nữa.

CẬP NHẬT: muppy cũng rất thuận tiện (và được ghi nhận tài liệu tốt hơn nhiều so với guppy/heapy).

+0

Của bạn là câu trả lời được chấp nhận của tôi nhưng tôi không phải là người đã đặt câu hỏi vì vậy điều tốt nhất tôi có thể cung cấp cho bạn là một câu trả lời. – CashCow

+0

Xin cảm ơn! Tôi đã tìm thấy [muppy] (http://packages.python.org/Pympler/muppy.html) để thậm chí còn tốt hơn theo một số cách, và cũng rất độc đáo được ghi lại - nó đáng để kiểm tra nếu bạn có vấn đề rò rỉ bộ nhớ. – johndodo

+0

Để biết chi tiết cụ thể, hãy xem câu trả lời (gần như giống nhau): http://stackoverflow.com/a/21632554/1959808 –

0

/proc/self/status có các phím có liên quan sau đây:

  • VmPeak: Đỉnh kích thước bộ nhớ ảo.
  • VmSize: Kích thước bộ nhớ ảo.
  • VmHWM: Kích thước bộ thường trú tối đa ("dấu nước cao").
  • VmRSS: Kích thước bộ thường trú.

Vì vậy, nếu người ta lo ngại bộ nhớ thường trú, đoạn code sau tôi có thể sử dụng để lấy nó:

def get_proc_status(keys = None): 
    with open('/proc/self/status') as f: 
     data = dict(map(str.strip, line.split(':', 1)) for line in f) 

    return tuple(data[k] for k in keys) if keys else data 

peak, current = get_proc_status(('VmHWM', 'VmRSS')) 
print(peak, current) # outputs: 14280 kB 13696 kB 

Dưới đây là một article by memory_profiler's author đó giải thích rằng getrusage 's ru_maxrss không phải lúc nào cũng là một biện pháp thực tế. Cũng lưu ý rằng, VmHWM có thể khác với ru_maxrss (những gì tôi thấy trong một số trường hợp là ru_maxrss lớn hơn). Nhưng trong trường hợp đơn giản họ đều giống nhau:

import resource 


def report(): 
    maxrss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
    peak, current = get_proc_status(('VmHWM', 'VmRSS')) 
    print(current, peak, maxrss) 


report() 

s = ' ' * 2 ** 28 # 256MiB 
report() 

s = None 
report() 

Bên cạnh đó đây là một rất dễ hiểu nhưng thông tin case study by atop authors điều này giải thích là những gì hạt nhân, bộ nhớ ảo và cư dân, và làm thế nào họ phụ thuộc lẫn nhau.

Các vấn đề liên quan