1

[编辑以简化示例/更好地隔离问题]

对同一个URLRoboBrowser进行多次后续访问会导致内存随着每次访问而增长,即使您每次都重新初始化并覆盖原始RoboBrowser实例也是如此。这违背了我对 Python 中内存管理如何工作的直觉,我想了解原因。

为了证明这一点,这里有一个脚本的内存配置文件,该脚本访问https://news.ycombinator.com/ask并获取所有 div(我故意重复此操作,以便内存配置文件更完整):

Line #    Mem usage    Increment   Line Contents
================================================
     5   19.684 MiB    0.000 MiB   @profile
     6                             def scrape():
     7
     8   19.684 MiB    0.000 MiB       url='https://news.ycombinator.com/ask'
     9
    10   19.719 MiB    0.035 MiB       browser = RoboBrowser(parser="html.parser", history=0)
    11   25.102 MiB    5.383 MiB       browser.open(url)
    12   26.598 MiB    1.496 MiB       browser.find_all('div')
    13
    14   26.602 MiB    0.004 MiB       time.sleep(1)
    15
                                       # re-initialising the browser doesn't free up memory:
    16   26.609 MiB    0.008 MiB       browser = RoboBrowser(parser="html.parser", history=0)
    17   27.535 MiB    0.926 MiB       browser.open(url)
    18   27.859 MiB    0.324 MiB       browser.find_all('div')
    19
                                       # also doesn't free up memory:
    20   27.859 MiB    0.000 MiB       browser = None

这是一个按我预期工作的不同脚本:

Line #    Mem usage    Increment   Line Contents
================================================
     5   20.102 MiB    0.000 MiB   @profile
     6                             def make_string():
     7   20.148 MiB    0.000 MiB       a = 'a'*1000000
     8   21.109 MiB    0.961 MiB       a = a + 'a'
     9   20.148 MiB   -0.961 MiB       a = None        # memory usage drops as expected

为什么在抓取时分配的内存会不断堆积?我应该研究什么才能更好地理解这个问题?

我正在通过python -m memory_profiler mem_test.py使用 Python 2.7.6运行来生成抓取内存配置文件

完整脚本mem_test.py

导入时间 从 robobrowser.browser 导入 memory_profiler 导入 RoboBrowser

@profile
def scrape():

    url='https://news.ycombinator.com/ask'

    browser = RoboBrowser(parser="html.parser", history=0)
    browser.open(url)
    browser.find_all('div')

    time.sleep(1)

    browser = RoboBrowser(parser="html.parser", history=0)
    browser.open(url)
    browser.find_all('div')

    browser = None

if __name__=='__main__':
    scrape()
4

0 回答 0