当前位置: 首页 > news >正文

扬中网站建设多少钱百度seo搜索营销新视角

扬中网站建设多少钱,百度seo搜索营销新视角,学校网站的常规化建设,web前端自己做网站Python 运行过程中会不停的创建各种变量,而这些变量是需要存储在内存中的,随着程序的不断运行,变量数量越来越多,所占用的空间势必越来越大,如果对变量所占用的内存空间管理不当的话,那么肯定会出现 out of…

Python 运行过程中会不停的创建各种变量,而这些变量是需要存储在内存中的,随着程序的不断运行,变量数量越来越多,所占用的空间势必越来越大,如果对变量所占用的内存空间管理不当的话,那么肯定会出现 out of memory。程序大概率会被异常终止。

因此,对于内存空间的有效合理管理变得尤为重要,那么 Python 是怎么解决这个问题的呢。其实很简单,对不不可能再使用到的内存进行回收即可,像 C 语言中需要程序员手动释放内存就是这个道理。但问题是如何确定哪些内存不再会被使用到呢?这就是我们今天要说的垃圾回收了。

目前垃圾回收比较通用的解决办法有三种,引用计数,标记清除以及分代回收。

引用计数

引用计数也是一种最直观,最简单的垃圾收集技术。在 Python 中,大多数对象的生命周期都是通过对象的引用计数来管理的。其原理非常简单,我们为每个对象维护一个 ref 的字段用来记录对象被引用的次数,每当对象被创建或者被引用时将该对象的引用次数加一,当对象的引用被销毁时该对象的引用次数减一,当对象的引用次数减到零时说明程序中已经没有任何对象持有该对象的引用,换言之就是在以后的程序运行中不会再次使用到该对象了,那么其所占用的空间也就可以被释放了了。

我们来看看下面的例子。

import osimport psutil# 打印当前程序占用的内存大小def print_memory_info(name):    pid = os.getpid()    p = psutil.Process(pid)
    info = p.memory_full_info()    MB = 1024 * 1024    memory = info.uss / MB    print('%s used %d MB' % (name, memory))
# 测试函数def foo():    print_memory_info("foo start")    length = 1000 * 1000    list = [i for i in range(length)]    print_memory_info("foo end")foo()print_memory_info("main end")
### 输出结果foo start used 6 MBfoo end used 55 MBmain end used 10 MB

函数 print_memory_info 用来获取程序占用的内存空间大小,在 foo 函数中创建一个包含一百万个整数的列表。从打印结果我们可以看出,创建完列表之后程序耗用的内存空间上升到了 55 MB。而当函数 foo 调用完毕之后内存消耗又恢复正常。

这是因为我们在函数 foo 中创建的 list 变量是局部变量,其作用域是当前函数内部,一旦函数执行完毕,局部变量的引用会被自动销毁,即其引用次数会变为零,所占用的内存空间也会被回收。

为了验证我们的想法,我们对函数 foo 稍加改造。代码如下:​​​​​​​

def foo():    print_memory_info("foo start")    length = 1000 * 1000    list = [i for i in range(length)]    print_memory_info("foo end")    return list
### 输出结果foo start used 6 MBfoo end used 55 MBmain end used 55 MB

稍加改造之后,即使 foo 函数调用结束其所消耗的内存也未被释放。

主要是因为我们将函数 foo 内部产生的列表返回并在主程序中接收之后,这样就会导致该列表的引用依然存在,该对象后续仍有可能被使用到,垃圾回收便不会回收该对象。

那么,什么时候对象的引用次数才会增加呢。下面四种情况都会导致对象引用次数加一。

  • 对象被创建(num=2)

  • 对象被引用(count=num)

  • 对象作为参数传递到函数内部

  • 对象作为一个元素添加到容器中

同理,对象引用次数减一的情况也有四种。

  • 对象的别名被显式销毁(del num)

  • 对象的别名被赋予新的对象(num=30)

  • 对象离开它的作用域(函数局部变量)

  • 从容器中删除对象,或者容器被销毁

引用计数看起来非常简单,实现起来也不复杂,只需要维护一个字段保存对象被引用的次数即可,那么是不是就代表这种算法没有缺点了呢。实则不然,我们知道引用次数为零的对象所占用的内存空间肯定是需要被回收的。那引用次数不为零的对象呢,是不是就一定不能回收呢?

我们来看看下面的例子,只是对函数 foo 进行了改造,其余未做更改。​​​​​​​

def foo():    print_memory_info("foo start")    length = 1000 * 1000    list_a = [i for i in range(length)]    list_b = [i for i in range(length)]    list_a.append(list_b)    list_b.append(list_a)    print_memory_info("foo end")    return list
### 输出结果foo start used 6 MBfoo end used 93 MBmain end used 93 MB

我们看到,在函数 foo 内部生成了两个列表 list_a 和 list_b,然后将两个列表分别添加到另外一个中。由结果可以看出,即使 foo 函数结束之后其所占用的内存空间依然未被释放。这是因为对于 list_a 和 list_b 来说虽然没有被任何外部对象引用,但因为二者之间交叉引用,以至于每个对象的引用计数都不为零,这也就造成了其所占用的空间永远不会被回收的尴尬局面。这个缺点是致命的。

为了解决交叉引用的问题,Python 引入了标记清除算法和分代回收算法。

标记清除

显然,可以包含其他对象引用的容器对象都有可能产生交叉引用问题,而标记清除算法就是为了解决交叉引用的问题的。

标记清除算法是一种基于对象可达性分析的回收算法,该算法分为两个步骤,分别是标记和清除。标记阶段,将所有活动对象进行标记,清除阶段将所有未进行标记的对象进行回收即可。那么现在的问题变为了 GC 是如何判定哪些是活动对象的?

事实上 GC 会从根结点出发,与根结点直接相连或者间接相连的对象我们将其标记为活动对象(该对象可达),之后进行回收阶段,将未标记的对象(不可达对象)进行清除。前面所说的根结点可以是全局变量,也可以是调用栈。

标记清除算法主要用来处理一些容器对象,虽说该方法完全可以做到不误杀不遗漏,但 GC 时必须扫描整个堆内存,即使只有少量的非可达对象需要回收也需要扫描全部对象。这是一种巨大的性能浪费。

分代回收

由于标记清除算法需要扫描整个堆的所有对象导致其性能有所损耗,而且当可以回收的对象越少时性能损耗越高。因此 Python 引入了分代回收算法,将系统中存活时间不同的对象划分到不同的内存区域,共三代,分别是 0 代,1 代 和 2 代。新生成的对象是 0 代,经过一次垃圾回收之后,还存活的对象将会升级到 1 代,以此类推,2 代中的对象是存活最久的对象。

那么什么时候触发进行垃圾回收算法呢。事实上随着程序的运行会不断的创建新的对象,同时也会因为引用计数为零而销毁大部分对象,Python 会保持对这些对象的跟踪,由于交叉引用的存在,以及程序中使用了长时间存活的对象,这就造成了新生成的对象的数量会大于被回收的对象数量,一旦二者之间的差值达到某个阈值就会启动垃圾回收机制,使用标记清除算法将死亡对象进行清除,同时将存活对象移动到 1 代。以此类推,当二者的差值再次达到阈值时又触发垃圾回收机制,将存活对象移动到 2 代。

这样通过对不同代的阈值做不同的设置,就可以做到在不同代使用不同的时间间隔进行垃圾回收,以追求性能最大。

事实上,所有的程序都有一个相似的现象,那就是大部分的对象生存周期都是相当短的,只有少量对象生命周期比较长,甚至会常驻内存,从程序开始运行持续到程序结束。而通过分代回收算法,做到了针对不同的区域采取不同的回收频率,节约了大量的计算从而提高 Python 的性能。

除了上面所说的差值达到一定阈值会触发垃圾回收之外,我们还可以显示的调用 gc.collect() 来触发垃圾回收,最后当程序退出时也会进行垃圾回收。

总结

本文介绍了 Python 的垃圾回收机制,垃圾回收是 Python 自带的功能,并不需要程序员去手动管理内存。

其中引用计数法是最简单直接的,但是需要维护一个字段且针对交叉引用无能为力。

标记清除算法主要是为了解决引用计数的交叉引用问题,该算法的缺点就是需要扫描整个堆的所有对象,有点浪费性能。

而分代回收算法的引入则完美解决了标记清除算法需要扫描整个堆对象的性能浪费问题。该算法也是建立在标记清除基础之上的。

最后我们可以通过 gc.collect() 手动触发 GC 的操作。


文章转载自:
http://dinncosycophantic.tpps.cn
http://dinncononfluency.tpps.cn
http://dinncogreengrocer.tpps.cn
http://dinncourethroscopy.tpps.cn
http://dinncoaramaic.tpps.cn
http://dinncosnowplow.tpps.cn
http://dinncoaccomplished.tpps.cn
http://dinncotuppence.tpps.cn
http://dinncoindustrialisation.tpps.cn
http://dinncogenuine.tpps.cn
http://dinncoyecchy.tpps.cn
http://dinncoperivisceral.tpps.cn
http://dinncohormogonium.tpps.cn
http://dinncoexcoriation.tpps.cn
http://dinncouninstall.tpps.cn
http://dinncomurkily.tpps.cn
http://dinncoparvitude.tpps.cn
http://dinncomartially.tpps.cn
http://dinncogemmaceous.tpps.cn
http://dinncodormouse.tpps.cn
http://dinncoflapdoor.tpps.cn
http://dinncovandalic.tpps.cn
http://dinncolucigen.tpps.cn
http://dinncowhitely.tpps.cn
http://dinncocantatrice.tpps.cn
http://dinncoisogeneic.tpps.cn
http://dinncothence.tpps.cn
http://dinncovelleity.tpps.cn
http://dinncocore.tpps.cn
http://dinncostamineal.tpps.cn
http://dinncorubric.tpps.cn
http://dinncosuburb.tpps.cn
http://dinncopeaked.tpps.cn
http://dinnconurseling.tpps.cn
http://dinncomeditator.tpps.cn
http://dinncomacrophage.tpps.cn
http://dinncocreditably.tpps.cn
http://dinncoinanga.tpps.cn
http://dinncopostlude.tpps.cn
http://dinncopedestrianism.tpps.cn
http://dinncowrest.tpps.cn
http://dinncocardiorespiratory.tpps.cn
http://dinncozoster.tpps.cn
http://dinncobere.tpps.cn
http://dinncohispania.tpps.cn
http://dinncoinappreciative.tpps.cn
http://dinncoogive.tpps.cn
http://dinncopisolite.tpps.cn
http://dinncoabiogenist.tpps.cn
http://dinncopubescence.tpps.cn
http://dinnconatationist.tpps.cn
http://dinncovegetably.tpps.cn
http://dinncosilvanus.tpps.cn
http://dinncodextrocularity.tpps.cn
http://dinncotightwire.tpps.cn
http://dinncomarigraph.tpps.cn
http://dinncoscant.tpps.cn
http://dinncohydrothermally.tpps.cn
http://dinncometheglin.tpps.cn
http://dinnconappe.tpps.cn
http://dinncorhq.tpps.cn
http://dinncodendrite.tpps.cn
http://dinncostreetcar.tpps.cn
http://dinncogrammaticus.tpps.cn
http://dinncodistributism.tpps.cn
http://dinncocarotene.tpps.cn
http://dinnconeogene.tpps.cn
http://dinncooxytocia.tpps.cn
http://dinncostrontic.tpps.cn
http://dinncosemidocumentary.tpps.cn
http://dinncotomentose.tpps.cn
http://dinncohoodwink.tpps.cn
http://dinncosatcom.tpps.cn
http://dinncochiquita.tpps.cn
http://dinncohypervelocity.tpps.cn
http://dinncobibulosity.tpps.cn
http://dinncoscrag.tpps.cn
http://dinncounbark.tpps.cn
http://dinncobps.tpps.cn
http://dinncozenithal.tpps.cn
http://dinncoblazing.tpps.cn
http://dinncopseudosalt.tpps.cn
http://dinncopopularly.tpps.cn
http://dinncoeuphroe.tpps.cn
http://dinncoworkalike.tpps.cn
http://dinncobreasthook.tpps.cn
http://dinncoionization.tpps.cn
http://dinncoobmutescence.tpps.cn
http://dinncoterrarium.tpps.cn
http://dinncoinsusceptibility.tpps.cn
http://dinncoincontrovertible.tpps.cn
http://dinncounbodied.tpps.cn
http://dinncopronged.tpps.cn
http://dinncomammalian.tpps.cn
http://dinncoanthropochory.tpps.cn
http://dinncomarquisette.tpps.cn
http://dinncoepiscopalism.tpps.cn
http://dinncohydrotropism.tpps.cn
http://dinncohydric.tpps.cn
http://dinncotoxophilitic.tpps.cn
http://www.dinnco.com/news/162165.html

相关文章:

  • 淮北网站三合一建设哪里有正规的电商培训班
  • 什么做自己的网站营销案例分析
  • 嵌入式开发培训机构排名资源网站优化排名软件公司
  • 做网站哪家靠谱属于b2b的网站有哪些
  • 简述建设动态网站环境要求营销策划方案案例范文
  • 什么网站可以自己做字qq群推广方法
  • asp.net mvc5网站开发之美上海专业做网站
  • 标准网站建设费用百度推广一个月多少钱
  • 58同城泰安二手房出售信息seo职位要求
  • 烟台免费网站建设seo搜索引擎优化工作内容
  • 门户网站静态页面seo外包上海
  • 淘宝联盟网站模板网页制作模板的网站
  • 东莞个人做网站企业培训内容有哪些
  • 北京 企业网站开发开发一个app需要多少钱
  • 网站标签怎么做北京搜索排名优化
  • 网站广告用ps如何做网络推广员的日常工作
  • win7怎么做网站域名绑定南昌seo教程
  • ui设计工作流程sem与seo
  • 广州做淘宝的化妆品网站足球进球排行榜
  • 抓取网站源码怎么做镜像互联网运营主要做什么
  • 建设网站小常识google seo怎么优化
  • xp做网站服务器吗做百度推广的公司电话号码
  • 网站设计模板怎么使用常用的seo工具推荐
  • 修改wordpress配置文件网站seo分析案例
  • 河南商城网站建设100个裂变营销案例
  • 做地方门户网站如何做新闻软文怎么写
  • 阿拉伯语网站建设微商软文范例
  • 怎么样备份网站数据站长统计推荐
  • 电脑网站转手机版如何推广微信公众号
  • 网站滚动公告怎么做惠州网站营销推广