当前位置: 首页 > 网络应用技术

在Python中发布资源需要多长时间

时间:2023-03-08 17:09:08 网络应用技术

  简介:许多朋友询问有关在Python释放资源需要多长时间的问题。本文的首席执行官注释将为您提供详细的答案,以供您参考。我希望这对每个人都会有所帮助!让我们一起看看!

  在上面的优化中,每500名用户将被计算并记录在磁盘文件中。但是实际上,Python的大坑是Python不会自动清洁这些内存。这是由本身决定的。出于特定的原因,互联网上有许多文章。

  该博客将贴上作者的实验脚本,以解释Python确实具有不发布记忆的现象。另外,还提出了一个解决方案,即:首先DEL,然后显示GC.Collect()。脚本和详细信息以下。

  实验环境1:Win 7,Python 2.7

  [python]查看普通副本

  从时间进口睡眠,时间

  导入GC

  DEF MEM(Way = 1):

  打印时间()

  对于我的范围(10000000):

  如果== 1:

  经过

  else:#路2、3

  熟食店

  打印时间()

  如果== 1或way == 2:

  经过

  else:#路3

  gc.collect()

  打印时间()

  如果__name__ ==“ __ -main __”:

  打印“测试方式1:正好通过”

  mem(路= 1)

  睡眠(20)

  打印“测试方式2:Just Del”

  mem(路= 2)

  睡眠(20)

  打印“测试方式3:del,然后是gc.collect()”

  mem(路= 3)

  睡眠(20)

  运行结果如下:

  [播放]查看普通副本

  测试方式1:只需通过

  1426688589.47

  1426688590.25

  1426688590.25

  测试方式2:只是DEL

  1426688610.25

  1426688611.05

  1426688611.05

  测试方式3:DEL,然后是GC.Collect()

  1426688631.05

  1426688631.85

  1426688631.95

  对于路1和路2,结果完全相同。程序内存消耗的峰值为326772KB。当睡眠20秒时,记忆的真实时间消耗为244820kb;

  对于3条,程序内存消耗的峰值与上述相同,但是在睡眠期间,实际时间消耗仅为6336KB。

  实验环境2:Ubuntu 14.10,Python 2.7.3

  操作结果:

  [播放]查看普通副本

  测试方式1:只需通过

  1426689577.46

  1426689579.41

  1426689579.41

  测试方式2:只是DEL

  1426689599.43

  1426689601.1

  1426689601.1

  测试方式3:DEL,然后是GC.Collect()

  1426689621.12

  1426689622.8

  1426689623.11

  [播放]查看普通副本

  ubuntu@my_machine:?ps -aux |GREP TEST_MEM

  警告:不好的PS语法,也许是虚假的' - '?看

  Ubuntu 9122 10.0 6.0 270916 245564 PTS/1 S+ 14:39 0:03 Python Test_mem.py

  ubuntu 9134 0.0 0.0 8104 924 pts/2 s+ 14:40 0:00 grep -color = auto test_mem

  ubuntu@my_machine:?ps -aux |GREP TEST_MEM

  警告:不好的PS语法,也许是虚假的' - '?看

  Ubuntu 9122 10.0 6.0 270916 245564 PTS/1 S+ 14:39 0:03 Python Test_mem.py

  ubuntu 9134 0.0 0.0 8104 924 pts/2 s+ 14:40 0:00 grep -color = auto test_mem

  ubuntu@my_machine:?ps -aux |GREP TEST_MEM

  警告:不好的PS语法,也许是虚假的' - '?看

  Ubuntu 9122 11.6 0.1 30956 5608 PTS/1 S+ 14:39 0:05 Python Test_mem.py

  综上所述:

  以上表明,当调用DEL时,Python并没有真正发布内存,而是会继续将其放在内存池中。只有在GC.Collect()中显示它,才能真正发布内存。

  更远:

  实际上,返回上一个博客的脚本,让它介绍gc.collect(),然后编写监视脚本监视内存消耗:

  [播放]查看普通副本

  而((1));做ps -aux |排序-n -k5,6 |grep my_script;自由的;睡眠5;完毕

  发现每组用户执行后没有恢复内存,但是它继续消耗直到仅存储了约70MB,而GC似乎有效。在此环境中,机器使用云实例,带有总存储器在2G,大约1G的可用内存中,此脚本内存的常用消耗为900m -1g。在换句话说,对于此脚本,GC不立即工作,但是当系统可用内存从1-1.2降低时G到只有约70m,GC开始扮演角色。这真的很奇怪。我不知道该脚本是否与线程中使用的gc.collect()或GC游戏不可控制有关。

  但是,可以肯定的是,如果您不使用gc.collect(),则原始脚本将在系统中耗尽并杀死。从系统列表可以清楚地看到这一点。

  众所周知,Python是一种面向对象的语言。在python中,无论是值,字符串,函数还是类型,类和类,它都是对象。

  对象是堆上的结构化结构。我们定义的所有变量和函数都存储在堆内存中,变量名称和函数名称是对堆栈中存储并指向堆的特定结构的引用。

  要深入了解Python,您首先需要了解Python对象的定义。

  我们通常说的Python是Cpython,底层由C语言实现,源代码地址:CPYTHON [GITHUB]

  python对象的定义位于include/object.h中。这是一种称为PyObject的结构:

  Python中的所有对象均从Pyobejct继承。PyObject包含垃圾回收的两条链接列表。

  从pyobejct的注释中,我们可以看到这样的句子:指向变量 - 尺寸python对象的可怜的指针也可以转换为pyvarobject*(在以下内容中可以解释pyvarobject*(可变 - 尺寸尺寸python对象).pyvarobejct)。根据PyObject存储存储元素的数量:

  在PyObject结构中,还有一个类型的对象指针OB_TYPE,用于表示哪种类型的Python对象。定义Python对象类型是PyTypeObject接口正文

  实际定义是_typeobject,位于include/cpython/object.h:

  在这种类型的对象中,不仅是对象的类型,还包括分配内存,对象标准操作等信息,它们主要分为:

  以python中的int类型为例,int类型对象的定义如下:

  从pyobject的定义来看,我们知道每个对象的ob_type必须指向特定类型对象,例如数值对象100,其ob_type将指向int类型对象pylong_type。

  Pytypeobject结构的第一行是PyObject_var_head宏。检查宏定义。

  换句话说,在最终分析中,类型的类型也是对象,并且还有一个ob_type属性。Pylong_type的ob_type是什么?

  返回到pyvarobject_head_init(pytype_type,0)的第一行,返回Pylong_type的定义,检查相应的宏定义

  从上面的关系中,我们可以知道pyvarobject_head_init(pytype_type,0)= {_pyobject_extra_init 1,pytype_type} 0} 0} 0}

  这很清楚。Pylong_type的类型是Pytype_typ。可以看出,python类型对象的类型是pytype_type,而pytype_type对象的类型本身本身本身本身

  从上面的内容中,我们知道对象和对象类型的定义,因此根据定义,对象可以具有以下两个类别

  Python对象用PyObject和PyvarObject定义。因此,根据对象大小是否是可变的,可以将python对象分为变量对象(长期对象)和无法变量对象(固定 - 长度对象)。

  原始对象a的大小没有更改,但是引用的对象已更改。对象A和对象B此处是固定长度对象

  可以看出,可变l仍指向对象A,但是对象A的内容已更改,并且数据量已更大。请注意,这里是一个长对象

  由于上述特征,这两个对象的使用将带来区别:

  状态s2 = s,修改s:s ='新字符串'的值,s2的值不会一起变化,因为s2指向一个新对象,s2的旧对象的值不会更改尚未更改的旧对象。

  说明L2 = L的值。修改L:L.Append(6)的值。目前,L2的值将共同变化,因为L和L2指向同一对象,并且对象的内容由L。

  此外,对于字符串对象,Python还具有一组内存重用机制。如果两个字符串变量变量是相同的值,它们将共享相同的对象:

  对于数值对象,Python将在0到2 8内创建一个整数对象,即,共享0至256之间的数值对象:

  根据Python数据类型,可以将对象分为以下类别:

  有两种方法可以在Python,通用API和类型相关的API中创建对象

  这种类型的API通常以pyobject_xxx命名。它可以应用于任何Python对象,例如:

  使用pyobjecg_new创建一个数值对象:

  这种类型的API通常仅作用于一种类型的对象,例如:

  使用Pylong_fromlong创建一个数值对象:

  当我们使用Python声明变量时,无需将类型分配给变量。分配变量时,我们可以分配任何类型数据,例如:::

  从Python对象的定义来看,我们已经可以知道这种特征的原因。当Python创建一个对象时,将分配内存以进行初始化。一个通用指针PyObject*,指向该指针的对象的类型未修复,只能通过OB_TYPE属性的动态动态来判断物体。

  当管理和维护对象管理和维护对象时,Python使用参考计数来确定是否需要破坏内存中的对象。Python中的所有内容都是一个对象,所有对象都有参考计数ob_refcnt。

  当对象的参考计数减少到0时,Python将释放对象占用的内存和系统资源。

  但这并不意味着最终将发布内存空间,因为频繁释放内存的应用将大大降低Python的执行效率。因此,在Python中使用了内存对象池的技术。它未直接发布。当将来需要应用程序空间时,将从“内存对象池”中优先考虑。

  关闭()是发布资源。

  如果您不关闭(),则需要等到垃圾回收后。垃圾回收的时机不确定,无法控制。

  如果程序是命令,它将很快执行,并且可能不会产生很大的影响(注意:不要说这不是问题)。

  但是,如果该程序是一项服务,或者需要很长时间才能执行它,或者可以在很大程度上执行它,则可能导致资源耗尽,或者可能导致僵局。

  我认为这可能是因为您的PY文件在第一次启动后已将其编译到PYC文件中。重新启动时,加载了PYC,从而消除了编译阶段,因此速度很快。

  您可以尝试删除程序目录中的所有PYC或与PYC文件相对应的代码文件中的所有PYC,以查看它是否与第一个加载速度相同

  结论:以上是首席CTO注释引入的Python中释放资源所需多长时间的全部内容。我希望这对每个人都会有所帮助。如果您想了解有关此信息的更多信息,请记住要收集对该网站的关注。