Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 线程内存配置_Python_Multithreading_Memory Management_Memory Leaks - Fatal编程技术网

Python 线程内存配置

Python 线程内存配置,python,multithreading,memory-management,memory-leaks,Python,Multithreading,Memory Management,Memory Leaks,所以我希望这不是一个重复,但我要么没有找到适当的解决方案,要么就是我不是100%的对我所寻找的。我已经编写了一个程序来处理许多请求。我创建了一个线程 从许多api获取响应,例如:share.yandex.ru/gpp.xml?url=MY_url以及抓取博客 使用pythongoose提取文章,解析来自上述示例/json/的所有请求的响应 将解析结果返回主线程并插入数据库。 在需要收回我以前没有测试过的大量数据之前,一切都很顺利。这样做的主要原因是,它使我超过了共享Linux服务器512mb上的

所以我希望这不是一个重复,但我要么没有找到适当的解决方案,要么就是我不是100%的对我所寻找的。我已经编写了一个程序来处理许多请求。我创建了一个线程

从许多api获取响应,例如:share.yandex.ru/gpp.xml?url=MY_url以及抓取博客 使用pythongoose提取文章,解析来自上述示例/json/的所有请求的响应 将解析结果返回主线程并插入数据库。 在需要收回我以前没有测试过的大量数据之前,一切都很顺利。这样做的主要原因是,它使我超过了共享Linux服务器512mb上的共享内存限制,从而启动了kill。这应该足够了,因为只有几千个请求,尽管我可能错了。我正在清除主线程中的所有大型数据变量/对象,但这似乎也没有帮助

我在主函数上运行了一个memory_配置文件,该配置文件使用如下所示的线程类创建线程:

class URLThread(Thread):
    def __init__(self,request):
        super(URLThread, self).__init__()
        self.url = request['request']
        self.post_id = request['post_id']
        self.domain_id = request['domain_id']
        self.post_data = request['post_params']
        self.type = request['type']
        self.code = ""
        self.result = ""
        self.final_results = ""
        self.error = ""
        self.encoding = ""

    def run(self):
        try:
            self.request = get_page(self.url,self.type)
            self.code = self.request['code']
            self.result = self.request['result']
            self.final_results = response_handler(dict(result=self.result,type=self.type,orig_url=self.url ))
            self.encoding = chardet.detect(self.result)
            self.error = self.request['error']
        except Exception as e:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            errors.append((exc_type, fname, exc_tb.tb_lineno,e,'NOW()'))
            pass

@profile
def multi_get(uris,timeout=2.0):
    def alive_count(lst):
        alive = map(lambda x : 1 if x.isAlive() else 0, lst)
        return reduce(lambda a,b : a + b, alive)
    threads = [ URLThread(uri) for uri in uris ]
    for thread in threads:
        thread.start()
    while alive_count(threads) > 0 and timeout > 0.0:
        timeout = timeout - UPDATE_INTERVAL
        sleep(UPDATE_INTERVAL)
    return [ {"request":x.url,
              "code":str(x.code),
              "result":x.result,
              "post_id":str(x.post_id),
              "domain_id":str(x.domain_id),
              "final_results":x.final_results,
              "error":str(x.error),
              "encoding":str(x.encoding),
              "type":x.type}
            for x in threads ]
第一批请求的结果是这样的仅供参考,这是一个链接,因为这里的输出文本不可读,我不能粘贴html表或嵌入图像,除非我再获得2分:

它似乎不会在后续的过程中丢失任何内存,我一次批处理100个请求/线程。我的意思是,一旦一批线程完成,它们似乎会停留在内存中,并且每次运行另一批线程时,内存都会按如下方式添加:


我在这里做的事情真的很愚蠢吗?

当对象没有引用时,Python通常会释放该对象占用的内存。multi_get函数返回一个列表,其中包含对已创建的每个线程的引用。因此Python不太可能释放这些内存。但是我们需要看看调用multi_get的代码在做什么才能确定


要开始释放内存,您需要停止从此函数返回对线程的引用。或者,如果你想继续这样做,至少在delx的某个地方删除它们

Python并不总是自己清理干净,这里有一个厕所:啊,好吧,这很有意义。调用multi_get函数的代码只是一个简单的循环,通过一个包含请求和一些附加数据的列表,然后循环通过结果adn构建mysql插入。因此,如果我将线程对象转换为列表或其他更简单的对象/变量,则删除线程并返回该对象,而不是从multi_get返回可能正常工作的线程?是的,这样就可以了。尝试从multi_get函数返回Python原语,如字符串。这可能会奏效。