2011-01-25 35 views
8

Có cách nào để cấu hình bộ nhớ của một chương trình đa luồng bằng Python không?Làm cách nào để tôi có thể cấu hình bộ nhớ của chương trình đa luồng bằng Python?

Đối với cấu hình CPU, tôi đang sử dụng cProfile để tạo thống kê tiểu sử riêng biệt cho từng chuỗi và sau đó kết hợp chúng. Tuy nhiên, tôi không thể tìm thấy một cách để làm điều này với bộ nhớ profilers. Tôi đang sử dụng heapy.

Có cách nào kết hợp số liệu thống kê trong heapy như cProfile không? Hoặc bạn sẽ gợi ý những trình thu thập bộ nhớ nào khác phù hợp hơn cho nhiệm vụ này.

Một câu hỏi liên quan được hỏi cho profiling sử dụng CPU trên chương trình multi-thread: How can I profile a multithread program in Python?

Ngoài ra một câu hỏi khác liên quan đến các hồ sơ bộ nhớ: Python memory profiler

+0

Bạn không thích điều gì về giải pháp trong các câu hỏi khác? – Falmarri

+0

@Falmarri, tôi đang tìm kiếm một bộ nhớ 'profiler'. Đầu tiên chủ yếu là một trình biên dịch CPU. Cái thứ hai chỉ hoạt động cho một sợi đơn. –

+1

Các tính năng chính của chủ đề là họ chia sẻ bộ nhớ (trái ngược với quy trình). Làm thế nào để bạn mong đợi để cấu hình số liệu thống kê bộ nhớ khác nhau cho các chủ đề chia sẻ tất cả cùng một bộ nhớ? – scoffey

Trả lời

7

Nếu bạn hài lòng với các đối tượng hồ sơ thay vì bộ nhớ thô, bạn có thể sử dụng chức năng gc.get_objects() để bạn không cần một metaclass tùy chỉnh. Trong các phiên bản Python mới hơn, sys.getsizeof() cũng sẽ cho phép bạn chụp ảnh để tìm ra số lượng bộ nhớ cơ bản đang được sử dụng bởi các đối tượng đó.

+0

Điều này thật tuyệt. Sạch hơn nhiều so với cách tiếp cận của tôi. –

3

Có nhiều cách để có được valgrind để cấu hình bộ nhớ của chương trình python: http://www.python.org/dev/faq/#can-i-run-valgrind-against-python

+0

Không bao giờ nghe nói về valgrind trước; Chắc chắn sẽ kiểm tra. –

+0

@funktku đây là một công cụ tiêu chuẩn để sử dụng bộ nhớ hồ sơ và phát hiện rò rỉ bộ nhớ. –

1

Ok. Những gì tôi đã tìm kiếm chính xác dường như không tồn tại. Vì vậy, tôi đã tìm thấy giải pháp-giải pháp cho vấn đề này.

Thay vì bộ nhớ hồ sơ, tôi sẽ cấu hình các đối tượng. Bằng cách này, tôi sẽ có thể thấy có bao nhiêu đối tượng tồn tại tại một thời điểm cụ thể trong chương trình. Để đạt được mục tiêu của mình, tôi đã sử dụng metaclasses với sự sửa đổi tối thiểu cho mã đã tồn tại.

Siêu dữ liệu sau đây thêm một chương trình con rất đơn giản cho các hàm __init____del__ của lớp. Chương trình con cho số __init__ tăng số lượng đối tượng có tên lớp đó lên một và số __del__ giảm một.

class ObjectProfilerMeta(type): 
    #Just set metaclass of a class to ObjectProfilerMeta to profile object 
    def __new__(cls, name, bases, attrs): 
     if name.startswith('None'): 
      return None 

     if "__init__" in attrs: 
      attrs["__init__"]=incAndCall(name,attrs["__init__"]) 
     else: 
      attrs["__init__"]=incAndCall(name,dummyFunction) 

     if "__del__" in attrs: 
      attrs["__del__"]=decAndCall(name,attrs["__del__"]) 
     else: 
      attrs["__del__"]=decAndCall(name,dummyFunction) 

     return super(ObjectProfilerMeta, cls).__new__(cls, name, bases, attrs) 

    def __init__(self, name, bases, attrs): 
     super(ObjectProfilerMeta, self).__init__(name, bases, attrs) 


    def __add__(self, other): 
     class AutoClass(self, other): 
      pass 
     return AutoClass 

Hàm incAndCall và decAndCall sử dụng biến toàn cầu của mô-đun mà chúng tồn tại.

counter={} 
def incAndCall(name,func): 
    if name not in counter: 
     counter[name]=0 

    def f(*args,**kwargs): 
     counter[name]+=1 
     func(*args,**kwargs) 

    return f 

def decAndCall(name,func): 
    if name not in counter: 
     counter[name]=0 

    def f(*args,**kwargs): 
     counter[name]-=1 
     func(*args,**kwargs) 

    return f 

def dummyFunction(*args,**kwargs): 
    pass 

Hàm giả chỉ là giải pháp rất đơn giản. Tôi chắc chắn có nhiều cách tốt hơn để làm điều đó.

Cuối cùng, bất cứ khi nào bạn muốn xem số lượng đối tượng tồn tại, bạn chỉ cần xem từ điển truy cập. Một ví dụ;

>>> class A: 
    __metaclass__=ObjectProfilerMeta 
    def __init__(self): 
     pass 


>>> class B: 
    __metaclass__=ObjectProfilerMeta 


>>> l=[] 
>>> for i in range(117): 
    l.append(A()) 


>>> for i in range(18): 
    l.append(B()) 


>>> counter 
{'A': 117, 'B': 18} 
>>> l.pop(15) 
<__main__.A object at 0x01210CB0> 
>>> counter 
{'A': 116, 'B': 18} 
>>> l=[] 
>>> counter 
{'A': 0, 'B': 0} 

Tôi hy vọng điều này sẽ giúp ích cho bạn. Đó là đủ cho trường hợp của tôi.

0

Tôi đã sử dụng Yappi, mà tôi đã thành công với một vài trường hợp đa luồng đặc biệt. Nó có tài liệu tuyệt vời vì vậy bạn không nên có quá nhiều rắc rối khi thiết lập nó.

Để biết thông tin cụ thể về bộ nhớ, hãy xem Heapy. Được cảnh báo, nó có thể tạo ra một số tệp nhật ký lớn nhất mà bạn từng thấy!

+0

Thật không may tôi nhận thức được cả hai hồ sơ này và đã liên kết đến các câu hỏi liên quan cụ thể nói về Yappi và Heapy. Vấn đề là, yappi không cấu hình bộ nhớ và hồ sơ chỉ heapy chủ đề sử dụng bộ nhớ chính (chính xác hơn các chủ đề nó được gọi là từ). –

+0

@KushalP. Tôi đã thử Yaapi, tôi nghĩ rằng nó không thể cho thời gian thực hiện từng dòng của tôi. Tôi có nhớ điều gì không? –

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