zoukankan      html  css  js  c++  java
  • Python-内存泄漏 持续增长 检查点

    仅个人目前遇见的内存问题, 可能不适用所有问题

    一下只是简单的实例代码, 可能跑不起来, 只是看看

    可变变量参数

    小例子:

    def foo(a, b=[]):
        b.append(a)
        print b
    # 
    input: foo(1)
    output: [1]
    
    # 
    input: foo(2)
    output: [1,2]

    解释说明:

    参考: http://tianshu.xyz/blog/82/

    官方文档中的一句话:

    Default values are computed once, then re-used.

    默认值是被重复使用的

    Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call.

    所以当默认参数值是可变对象的时候,那么每次使用该默认参数的时候,其实更改的是同一个变量

    当python执行def语句时,它会根据编译好的函数体字节码和命名空间等信息新建一个函数对象,并且会计算默认参数的值。函数的所有构成要素均可通过它的属性来访问,比如可以用funcname属性来查看函数的名称。所有默认参数值则存储在函数对象的defaults_属性中,它的值为一个列表,列表中每一个元素均为一个默认参数的值

    其中默认参数相当于函数的一个属性

    Functions in Python are first-class objects, and not only a piece of code.

    我们可以这样解读:函数也是对象,因此定义的时候就被执行,默认参数是函数的属性,它的值可能会随着函数被调用而改变。其他对象不都是如此吗?

    其实使用 id(b) 的内存地址就很清楚了

    解决:

    def foo(a, b=None):
            b = b if b is not None else []
            b.append(a)
            print b
    
    # 或者
    def foo(b=None):
        b = b or []

    使用pyquery

    小例子:

    import requests
    from pyquery import PyQuery
    
    def demo(url):
        html = requests.get(url).text
        print(html)
        pq_html = PyQuery(html)
        item_list = pq_html("#cm_cr-review_list>div[data-hook='review']")
        for item in item_list:
            iid = PyQuery(item)("div[data-hook='review']").attr("id")
            print(iid)
    
    
    if __name__ == "__main__":
        url = "评论页面链接"
        demo(url)

    项目说明

    这个是项目中的一部分, 抓取评论的页面:

    在将整个页面转为PyQuery的对象后, 提取出评论列表, 然后遍历评论列表, 再将每个评论的html转为PyQuery对象, 也个页面还好, 但是现在目前好像没有单线程爬虫了吧! 结果可想而知

    解决方法

    在看了PyQuery官方文档后, 发现可以这样:

        item_list = pq_html("#cm_cr-review_list>div[data-hook='review']")
        for item in item_list.items():
            iid = item("div[data-hook='review']").attr("id")
            print(iid)

    也可以使用xpath

        item_list = etree.HTML("#cm_cr-review_list>div[data-hook='review']")
        for item in item_list:
            iid = item.xpath("//div[@data-hook='review']/@id")
            print(iid)

    # from lxml import etree

    这样直接使用对象来进行提取元素, 会节省很大一部分内存

    使用requests session

    小例子

    import requests
    
    
    class Download(object):
        def __init__(self):
            self.session = requests.session()
    
        def down(self, url, try_time=10):
            while try_time:
                try:
                    response = self.session.get(url)
                except Exception as e:
                    print(e)
                finally:
                    try_time -= 1

    项目说明

    在使用session的时候, 内存会直线上升, 并且没有下降的趋势, 直到内存崩溃, 特别是重试的时候, 目前没有搞懂为什么session会这样? 希望懂的大神解释一下

    解决

    目前是不使用session, 直接使用requests.get()

    求大神赐教

    四. 持续更新......

    以后遇见的bug, 或者内存泄漏问题都会记录下来, 避免更多人踩坑 :)

    也希望大家可以补充自己遇见的大坑

  • 相关阅读:
    数组元素的查找1
    排序——选择排序
    排序——冒泡排序
    内部类——匿名内部类
    跳一跳
    数组元素换位置游戏
    六 java和Tomcat
    九 Jenkins持续集成
    八 ip和子网详解
    七 Git版本控制
  • 原文地址:https://www.cnblogs.com/mswei/p/11951181.html
Copyright © 2011-2022 走看看