我写了大约50个类,使用 mechanize 和 threading 连接和处理网站。它们都是并行工作的,但彼此之间没有依赖关系。这意味着每个类对应一个网站和一个线程。这不是特别优雅的解决方案,尤其是对于代码管理来说,因为很多代码在每个类中都重复出现(但不足以将其合并为一个类来传递参数,因为某些网站可能需要在方法中间(如“登录”)对检索到的数据进行额外的处理,而其他网站可能不需要)。正如我所说,这不太优雅——但它有效。毋庸置疑,我欢迎所有建议,以更好地编写此代码,而不使用每个网站一个类的方法。增加每个类的附加功能或整体代码管理是一项艰巨的任务。
然而,我发现每个线程占用大约8MB的内存,因此如果有50个运行的线程,我们将看到大约400MB的内存使用量。如果它在我的系统上运行,我不会有问题,但由于它在只有1GB内存的VPS上运行,这开始成为一个问题。您能告诉我如何减少内存使用量,或者有没有其他方法可以同时处理多个网站?
我使用了这个快速测试 Python 程序来测试是否是我的应用程序中存储的数据使用了内存,还是其他原因。正如您在以下代码中所看到的,它只处理 sleep() 函数,但每个线程都使用了8MB的内存。
当我运行此代码时,输出结果如下:
然而,我发现每个线程占用大约8MB的内存,因此如果有50个运行的线程,我们将看到大约400MB的内存使用量。如果它在我的系统上运行,我不会有问题,但由于它在只有1GB内存的VPS上运行,这开始成为一个问题。您能告诉我如何减少内存使用量,或者有没有其他方法可以同时处理多个网站?
我使用了这个快速测试 Python 程序来测试是否是我的应用程序中存储的数据使用了内存,还是其他原因。正如您在以下代码中所看到的,它只处理 sleep() 函数,但每个线程都使用了8MB的内存。
from thread import start_new_thread
from time import sleep
def sleeper():
try:
while 1:
sleep(10000)
except:
if running: raise
def test():
global running
n = 0
running = True
try:
while 1:
start_new_thread(sleeper, ())
n += 1
if not (n % 50):
print n
except Exception, e:
running = False
print 'Exception raised:', e
print 'Biggest number of threads:', n
if __name__ == '__main__':
test()
当我运行此代码时,输出结果如下:
50
100
150
Exception raised: can't start new thread
Biggest number of threads: 188
通过删除 running = False
这行代码,我可以使用 shell 命令 free -m
来测量可用内存:
total used free shared buffers cached
Mem: 1536 1533 2 0 0 0
-/+ buffers/cache: 1533 2
Swap: 0 0 0
实际计算表明,每个线程大约占用8MB的内存。具体方法是将上述测试应用程序运行期间使用的内存与之前使用的内存之差除以最大线程数。
这可能仅仅是分配的内存,因为通过查看top
,可以发现python进程仅使用了约0.6%的内存。
ulimit -u
呢?还有ulimit -a
呢? - dani herreraulimit -s
可以通过 limit pam 模块 进行修复,每个参数都有软限制和硬限制。此外,您可以在 bash.rc 中为每个用户分配自定义限制。例如,请参阅 Oracle 文档,Oracle 服务器需要自定义这些参数才能正常工作。 - dani herrera