pythontimer占用内存

pythontimer占用内存,第1张

python程序在运行过程之中会单独开辟出一个进程来执行,而很多小伙伴都发现程序在运行过程之中所占用的内存会越来越大,但是不知道是什么原因以及如何解决。那么下文会来讲解一下python程序内存占用过大的原因和解决方法,感兴趣的和有需要的话就往下看看吧。

一、原因

首先需要知道的一点就是,python是面向对象编程的语言,那么就表示在其程序之中一切皆为对象。而每一个对象在创建是都会在内存中开辟空间来占用位置,这样就会造成一开始的内存占用。

虽然说python中有自己的内存管理机制和垃圾处理方式,但是它对于一些占用内存过多的对象不会马上释放,只有当这个对象不处于引用状态时才会处理它。

二、解决方法

既然知道了python程序内存都是因为有对象才将其占用的,那么正确的解决方法就是将对象在调用完毕之后马上删除掉。该方法需要用到关键字del和gc模块,使用del关键字删除变量之后,调用gc模块来马上启动python垃圾处理机制就可以直接将其彻底从内存空间清除,代码示例如下所示:

由于python中万物皆对象,所以python的存储问题是对象的存储问题。实际上,对于每个对象,python会分配一块内存空间去存储它。

那么python是如何进行内存分配,如何进行内存管理,又是如何释放内存的呢?

总结起来有一下几个方面:引用计数,垃圾回收,内存池机制

python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数

1、对象被创建 a= 'abc'

2、对象被引用 b =a

3、对象被其他的对象引用 li = [1,2,a]

4、对象被作为参数传递给函数:foo(x)

1、变量被删除 del a 或者 del b

2、变量引用了其他对象 b = c 或者 a = c

3、变量离开了所在的作用域(函数调用结束) 比如上面的foo(x)函数结束时,x指向的对象引用减1。

4、在其他的引用对象中被删除(移除) li.remove(a)

5、窗口对象本身被销毁:del li,或者窗口对象本身离开了作用域。

即对象p中的属性引用d,而对象d中属性同时来引用p,从而造成仅仅删除p和d对象,也无法释放其内存空间,因为他们依然在被引用。深入解释就是,循环引用后,p和d被引用个数为2,删除p和d对象后,两者被引用个数变为1,并不是0,而python只有在检查到一个对象的被引用个数为0时,才会自动释放其内存,所以这里无法释放p和d的内存空间

垃圾回收机制: ① 引用计数 , ②标记清除 , ③分带回收

引用计数也是一种垃圾收集机制, 而且也是一种最直观, 最简单的垃圾收集技术.当python某个对象的引用计数降为 0 时, 说明没有任何引用指向该对象, 该对象就成为要被回收的垃圾了.(如果出现循环引用的话, 引用计数机制就不再起作用了)

优点:简单实时性,缺点:维护引用计数消耗资源,且无法解决循环引用。

如果两个对象的引用计数都为 1 , 但是仅仅存在他们之间的循环引用,那么这两个对象都是需要被回收的, 也就是说 它们的引用计数虽然表现为非 0 , 但实际上有效的引用计数为 0 ,.所以先将循环引用摘掉, 就会得出这两个对象的有效计数.

标记清除算法也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。

为了提高效率,有很多对象,清理了很多次他依然存在,可以认为,这样的对象不需要经常回收,可以把它分到不同的集合,每个集合回收的时间间隔不同。简单的说这就是python的分代回收。

具体来说,python中的垃圾分为1,2,3代,在1代里的对象每次回收都会去清理,当清理后有引用的对象依然存在,此时他会进入2代集合,同理2代集合清理的时候存在的对象会进入3代集合。

每个集合的清理时间如何分配:会先清理1代垃圾,当清理10次一代垃圾后会清理一次2代垃圾,当清理10次2代垃圾后会清理3代垃圾。

在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,当创建大量消耗小内存的对象时,频繁调用new/malloc会导致大量的内存碎片,致使效率降低。

内存池的概念就是预先在内存中申请一定数量的,大小相等的内存块留作备用,当有新的内存需求时,就先从内存池中分配内存给这个需求,不够了之后再申请新的内存。这样做最显著的优势就是能够减少内存碎片,提升效率。

Python中有分为大内存和小内存:(256K为界限分大小内存)

大小小于256kb时,pymalloc会在内存池中申请内存空间,当大于256kb,则会直接执行 new/malloc 的行为来申请新的内存空间

在python中 -5到256之间的数据,系统会默认给每个数字分配一个内存区域,其后有赋值时都会指向固定的已分配的内存区域

在运行py程序的时候,解释器会专门分配一块空白的内存,用来存放纯单词字符组成的字符串(数字,字母,下划线)

字符串赋值时,会先去查找要赋值的字符串是否已存在于内存区域,已存在,则指向已存在的内存,不存在,则会在大整数池中分配一块内存存放此字符串


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11746913.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存