2012-03-24 10 views
22

मैं यह जानना चाहता हूं कि किसी फ़ंक्शन में कॉल के दौरान आवंटित रैम की अधिकतम मात्रा (पायथन में) क्या है। ट्रैकिंग RAM उपयोग करने के लिए इतना संबंधित पर अन्य प्रश्न हैं:ट्रैकिंग * अधिकतम * मेमोरी उपयोग एक पायथन फ़ंक्शन

Which Python memory profiler is recommended?

How do I profile memory usage in Python?

लेकिन उन समय में स्मृति के उपयोग को ट्रैक करने के heap() विधि (गप्पी के मामले में) आप और अधिक अनुमति देने के लिए लग रहे हैं कहा जाता है। हालांकि, मैं जो ट्रैक करना चाहता हूं वह बाहरी पुस्तकालय में एक फ़ंक्शन है जिसे मैं संशोधित नहीं कर सकता, और जो बहुत सी रैम का उपयोग करने के लिए बढ़ता है लेकिन फ़ंक्शन निष्पादित होने के बाद इसे मुक्त कर देता है। क्या फ़ंक्शन कॉल के दौरान उपयोग की जाने वाली रैम की कुल मात्रा का पता लगाने का कोई तरीका है?

उत्तर

18

यह प्रश्न अपेक्षाकृत दिलचस्प लग रहा था और इससे मुझे गुप्पी/हेपी में देखने का कारण मिला, क्योंकि मैं आपको धन्यवाद देता हूं।

मैंने शून्य भाग्य के साथ अपने स्रोत को संशोधित किए बिना एक फंक्शन कॉल/प्रक्रिया की निगरानी करने के लिए हेपी प्राप्त करने के लिए लगभग 2 घंटे तक प्रयास किया।

मुझे पाइथन लाइब्रेरी resource में निर्मित अपने कार्य को पूरा करने का एक तरीका मिला। ध्यान दें कि दस्तावेज़ीकरण इंगित नहीं करता कि RU_MAXRSS मूल्य रिटर्न क्या है। एक अन्य SO उपयोगकर्ता noted कि यह केबी में था। मैक ओएसएक्स 7.3 चल रहा है और मेरे सिस्टम संसाधनों को नीचे दिए गए टेस्ट कोड के दौरान चढ़ते हुए, मेरा मानना ​​है कि लौटाए गए मान बाइट में नहीं हैं, केबीईटीएस नहीं।

लाइब्रेरी कॉल की निगरानी के लिए resource लाइब्रेरी का उपयोग करने के तरीके पर एक 10000 फीट दृश्य था कि फ़ंक्शन को एक अलग (मॉनिटर-सक्षम) थ्रेड में लॉन्च करना था और उस प्रक्रिया के लिए मुख्य संसाधन में सिस्टम संसाधनों को ट्रैक करना था। नीचे मेरे पास दो फाइलें हैं जिन्हें आपको परीक्षण करने के लिए चलाने की आवश्यकता होगी।

लाइब्रेरी संसाधन मॉनिटर - whatever_you_want.py

import resource 
import time 

from stoppable_thread import StoppableThread 


class MyLibrarySniffingClass(StoppableThread): 
    def __init__(self, target_lib_call, arg1, arg2): 
     super(MyLibrarySniffingClass, self).__init__() 
     self.target_function = target_lib_call 
     self.arg1 = arg1 
     self.arg2 = arg2 
     self.results = None 

    def startup(self): 
     # Overload the startup function 
     print "Calling the Target Library Function..." 

    def cleanup(self): 
     # Overload the cleanup function 
     print "Library Call Complete" 

    def mainloop(self): 
     # Start the library Call 
     self.results = self.target_function(self.arg1, self.arg2) 

     # Kill the thread when complete 
     self.stop() 

def SomeLongRunningLibraryCall(arg1, arg2): 
    max_dict_entries = 2500 
    delay_per_entry = .005 

    some_large_dictionary = {} 
    dict_entry_count = 0 

    while(1): 
     time.sleep(delay_per_entry) 
     dict_entry_count += 1 
     some_large_dictionary[dict_entry_count]=range(10000) 

     if len(some_large_dictionary) > max_dict_entries: 
      break 

    print arg1 + " " + arg2 
    return "Good Bye World" 

if __name__ == "__main__": 
    # Lib Testing Code 
    mythread = MyLibrarySniffingClass(SomeLongRunningLibraryCall, "Hello", "World") 
    mythread.start() 

    start_mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
    delta_mem = 0 
    max_memory = 0 
    memory_usage_refresh = .005 # Seconds 

    while(1): 
     time.sleep(memory_usage_refresh) 
     delta_mem = (resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) - start_mem 
     if delta_mem > max_memory: 
      max_memory = delta_mem 

     # Uncomment this line to see the memory usuage during run-time 
     # print "Memory Usage During Call: %d MB" % (delta_mem/1000000.0) 

     # Check to see if the library call is complete 
     if mythread.isShutdown(): 
      print mythread.results 
      break; 

    print "\nMAX Memory Usage in MB: " + str(round(max_memory/1000.0, 3)) 

stoppable थ्रेड - stoppable_thread.py

import threading 
import time 

class StoppableThread(threading.Thread): 
    def __init__(self): 
     super(StoppableThread, self).__init__() 
     self.daemon = True 
     self.__monitor = threading.Event() 
     self.__monitor.set() 
     self.__has_shutdown = False 

    def run(self): 
     '''Overloads the threading.Thread.run''' 
     # Call the User's Startup functions 
     self.startup() 

     # Loop until the thread is stopped 
     while self.isRunning(): 
      self.mainloop() 

     # Clean up 
     self.cleanup() 

     # Flag to the outside world that the thread has exited 
     # AND that the cleanup is complete 
     self.__has_shutdown = True 

    def stop(self): 
     self.__monitor.clear() 

    def isRunning(self): 
     return self.__monitor.isSet() 

    def isShutdown(self): 
     return self.__has_shutdown 


    ############################### 
    ### User Defined Functions #### 
    ############################### 

    def mainloop(self): 
     ''' 
     Expected to be overwritten in a subclass!! 
     Note that Stoppable while(1) is handled in the built in "run". 
     ''' 
     pass 

    def startup(self): 
     '''Expected to be overwritten in a subclass!!''' 
     pass 

    def cleanup(self): 
     '''Expected to be overwritten in a subclass!!''' 
     pass 
+0

धन्यवाद एमबी विभाजन में परिवर्तित करने के लिए! – astrofrog

+0

@astrofrog मदद करने के लिए खुशी हुई। यह कुछ ऐसा है जो मैं भविष्य में भी लाभ उठा सकता हूं। –

+0

मैंने इस कोड को एक गिस्ट के रूप में रखा है, इसलिए फ़ाइलों को डाउनलोड करना आसान है: https://gist.github.com/b54fafd87634f017d50d – Tom

11

यह memory_profiler के साथ ऐसा करना संभव है। फ़ंक्शन memory_usage मानों की एक सूची देता है, ये समय के साथ स्मृति उपयोग का प्रतिनिधित्व करते हैं (डिफ़ॉल्ट रूप से .1 सेकंड के भाग पर)। यदि आपको अधिकतम की आवश्यकता है, तो बस उस सूची का अधिकतम लें। लिटिल उदाहरण:

from memory_profiler import memory_usage 
from time import sleep 

def f(): 
    # a function that with growing 
    # memory consumption 
    a = [0] * 1000 
    sleep(.1) 
    b = a * 100 
    sleep(.1) 
    c = b * 100 
    return a 

mem_usage = memory_usage(f) 
print('Memory usage (in chunks of .1 seconds): %s' % mem_usage) 
print('Maximum memory usage: %s' % max(mem_usage)) 

मेरे मामले में (memory_profiler 0.25) प्रिंट निम्न उत्पादन करता है, तो:

Memory usage (in chunks of .1 seconds): [45.65625, 45.734375, 46.41015625, 53.734375] 
Maximum memory usage: 53.734375 
+1

शानदार समाधान। https://pypi.python.org/pypi/memory_profiler लेकिन psutil को अनस्टॉल करने की भी आवश्यकता है – mrgloom

+0

यह कोशिश करते समय कंसोल पर बस अटक जाता है .... – Wajahat

+0

आप @Wajahat का उपयोग किस सिस्टम का उपयोग कर रहे हैं? –

5

यह Windows के तहत काम करने के लिए प्रकट होता है। अन्य ऑपरेटिंग सिस्टम के बारे में पता नहीं है।

In [50]: import os 

In [51]: import psutil 

In [52]: process = psutil.Process(os.getpid()) 

In [53]: process.get_ext_memory_info().peak_wset 
Out[53]: 41934848 
+1

मेरा मानना ​​है कि यह 'memory_info_ex.peak_set' – gbronner

+0

दस्तावेज़ देखें। https://pythonhosted.org/psutil/#psutil.Process.memory_info क्रॉस प्लेटफॉर्म होने के लिए 'process.memory_info()। rss' होना चाहिए –

-2

इस कार्य के साथ भी संघर्ष कर रहा है। एडम से psutil और विधियों के साथ प्रयोग करने के बाद, मैंने एक विशिष्ट समारोह द्वारा उपयोग की गई स्मृति को मापने के लिए एक समारोह (एडम लुईस को क्रेडिट) लिखा था। लोगों को पकड़ना और उपयोग करना आसान हो सकता है।

1) measure_memory_usage

2) test measure_memory_usage

मैंने पाया कि सूत्रण और अधिभावी सुपर क्लास के बारे में सामग्री को समझने एडम उसकी स्क्रिप्ट में क्या कर रहा है में वास्तव में सहायक होते हैं। क्षमा करें मैं अपने "2 लिंक" अधिकतम सीमा के कारण लिंक पोस्ट नहीं कर सकता।

0

आप स्मृति उपयोग प्राप्त करने के लिए पाइथन लाइब्रेरी संसाधन का उपयोग कर सकते हैं।

आयात संसाधन resource.getrusage (resource.RUSAGE_SELF) .ru_maxrss

यह किलोबाइट में स्मृति उपयोग दे देंगे विस्तृत उत्तर के लिए द्वारा 1000

संबंधित मुद्दे