gpt4 book ai didi

python - 使用urllib2时如何解决Python内存泄漏?

转载 作者:太空狗 更新时间:2023-10-29 21:10:24 24 4
gpt4 key购买 nike

我正在尝试为我的手机编写一个简单的 Python 脚本,以使用 urrlib2 定期加载网页。事实上我并不真正关心服务器响应,我只想将 URL 中的一些值传递给 PHP。问题是 S60 的 Python 使用旧的 2.5.4 Python 核心,它似乎在 urrlib2 模块中有内存泄漏。正如我读到的那样,每种类型的网络通信中似乎也存在这样的问题。此错误已报告 here几年前,同时也发布了一些解决方法。在 Google 的帮助下,我已经尝试了在该页面上可以找到的所有内容,但我的手机在加载约 70 个页面后仍然内存不足。奇怪的是,Garbege Collector 似乎也没有任何区别,除了让我的脚本慢得多。据说,较新的 (3.1) 核心解决了这个问题,但不幸的是,我等不及一年(或更长时间)才能看到 S60 端口。

这是添加我发现的所有小技巧后我的脚本的样子:


import urrlib2, httplib, gc
while(true):
url = "http://something.com/foo.php?parameter=" + value
f = urllib2.urlopen(url)
f.read(1)
f.fp._sock.recv=None # hacky avoidance
f.close()
del f
gc.collect()
有什么建议,如何让它永远工作而不会出现“无法分配内存”错误?感谢您的提前,干杯,b_m

更新:在内存耗尽之前,我已经成功连接了 92 次,但仍然不够好。

更新 2:尝试了之前建议的套接字方法,这是迄今为止第二好的(错误的)解决方案:


class UpdateSocketThread(threading.Thread):
def run(self):
global data
while 1:
url = "/foo.php?parameter=%d"%data
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('something.com', 80))
s.send('GET '+url+' HTTP/1.0\r\n\r\n')
s.close()
sleep(1)
我也从上面尝试了这些小技巧。上传约 50 次后线程关闭(手机还剩 50MB 内存,显然 Python shell 没有。)

更新:我想我离解决方案越来越近了!我尝试在不关闭并重新打开套接字的情况下发送多个数据。这可能是关键,因为此方法只会留下一个打开的文件描述符。问题是:


import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect(("something.com", 80))
socket.send("test") #returns 4 (sent bytes, which is cool)
socket.send("test") #4
socket.send("test") #4
socket.send("GET /foo.php?parameter=bar HTTP/1.0\r\n\r\n") #returns the number of sent bytes, ok
socket.send("GET /foo.php?parameter=bar HTTP/1.0\r\n\r\n") #returns 0 on the phone, error on Windows7*
socket.send("GET /foo.php?parameter=bar HTTP/1.0\r\n\r\n") #returns 0 on the phone, error on Windows7*
socket.send("test") #returns 0, strange...
*: 错误消息:10053,软件导致连接中止

为什么我不能发送多条消息??

最佳答案

使用您的链接建议的测试代码,我测试了我的 Python 安装并确认它确实泄漏了。但是,如果像@Russell 所建议的那样,我将每个 urlopen 放入其自己的进程中,操作系统应该 清理内存泄漏。在我的测试中,内存、无法访问的对象和打开的文件都或多或少保持不变。我将代码分成两个文件:

连接.py

import cPickle, urllib2

def connectFunction(queryString):
conn = urllib2.urlopen('http://something.com/foo.php?parameter='+str(queryString))
data = conn.read()
outfile = ('sometempfile'. 'wb')
cPickle.dump(data, outfile)
outfile.close()

if __name__ == '__main__':
connectFunction(sys.argv[1])

###launcher.py
import subprocess, cPickle

#code from your link to check the number of unreachable objects

def print_unreachable_len():
# check memory on memory leaks
import gc
gc.set_debug(gc.DEBUG_SAVEALL)
gc.collect()
unreachableL = []

for it in gc.garbage:
unreachableL.append(it)
return len(str(unreachableL))

#my code
if __name__ == '__main__':
print 'Before running a single process:', print_unreachable_len()
return_value_list = []
for i, value in enumerate(values): #where values is a list or a generator containing (or yielding) the parameters to pass to the URL
subprocess.call(['python', 'connection.py', str(value)])
print 'after running', i, 'processes:', print_unreachable_len()
infile = open('sometempfile', 'rb')
return_value_list.append(cPickle.load(infile))
infile.close()

显然,这是顺序的,因此您一次只能执行一个连接,这对您来说可能是问题,也可能不是问题。如果是,您将必须找到一种非阻塞方式来与您正在启动的进程进行通信,但我会将其留作您的练习。

编辑:在重新阅读您的问题时,您似乎并不关心服务器响应。在这种情况下,您可以摆脱所有酸洗相关的代码。显然,您的最终代码中也不会有 print_unreachable_len() 相关位。

关于python - 使用urllib2时如何解决Python内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4214224/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com