美文网首页
python基础->内存分析和处理->垃圾回收机制

python基础->内存分析和处理->垃圾回收机制

作者: 也是如此 | 来源:发表于2018-08-22 22:25 被阅读17次

内存分析和处理

why:为什么要进行内存分析和处理?
软件->一个完整的软件加载运行流程->基于硬件
软件:处理数据->硬件中的数据->硬件(读|存)->内存(读|存)->缓存(运算)
一个软件运行时,优先向系统申请内存空间加载软件处理的数据
软件程序在计算机中的执行,主要是通过数据单元,控制单元,执行单元共同协作,完成数据的交互, 达到程序处理数据的目的,在软件执行的过程中,由于系统内存和CPU的资源非常有限,所以有效分解软件的各项数据,将不同的数据加载到不同的内存部分以有效的运行程序,同时可以达到在一个计算机中有效运行更多软件的目的

分配内存
python程序在运行过程中,主要是解释器从系统中申请内存空间以运行python软件,解释器将申请的内存主要区分为这几个部分用于处理执行的程序软件

栈内存区(Stack )
堆内存区(heap)
静态区|常量区(static)
方法区|数据区(data)

1.栈内存区(stack):用于直接分配数据,数据存储不稳定,适用于小数据块的快速存取,经常临时分配经常回收的数据->一般在程序中用于存储变量数据

2.方法区(data):主要用于加载程序中使用的代码数据,二进制数据,方法函数数据等等程序运行需要加载的预加载数据

3.静态区(static):主要用于加载存储程序中的一些静态数据,常量数据等等,在python中的不可变数据类型的数据,也会存储在静态常量区内存中

4.堆内存区(heap):读取,加载速度较慢,比较消耗资源,但是一旦数据存在,数据操作比较稳定,适合存放的数据:对象

代码执行
class Person:
pass
创建两个对象
p = Person()
p2 = Person()
print(p,p2)
每一个对象占据内存的起始的地方称为内存的首地址,一个数据在内存中开始存储数据的地方
p,p2在栈内存区,class Person()在堆内存区

可变数据类型<->不可变数据类型
python中根据数据是否可以进行修改提供了两种不同的数据类型
不可变数据类型->一般基本数据类型都是不可变数据类型
可变数据类型->一般组合数据类型或者自定义数据类型都是可变数据类型

如何区分?
python中的一切都是对象,可以通过id()函数查询对象在内存中的地址数据,地址一样,才能被称为数据类型一样
@@@可变数据类型:是在定义了数据之后,修改变量的数据,内存地址不会发生变化
a = list()->堆内存中,存在一个对象list(),一个变量a指向这个列表
@@@不可变数据类型:是在定义了数据之后,修改变量的数据,变量不会修改原来的内存信息地址,而是会指向新的地址,原有的数据保留,这样方便程序中基本数据的利用率

申请内存中的整数:-5~256:在解释器加载时,已经自动分派了这些数字的内存,使用时无需重复申请内存
超出范围的整数,在一个代码块中申请一次内存(代码块:交互模式下一行命令就是一个代码块,IDE模式中一个模块就是一个代码块)
b = 12
b = 13
print(id(b)) 不等于 print(id(b)),地址不一样
断掉12的地址,连接13的地址,12的地址和13的地址不一样

思考题:
nums = [12,23,42,45,"hello",["haha","nihao"]]
a = 12 和 nums[0]的内存地址 一样
b = "hello" 和 nums[4]的内存地址一样
c = ["haha","nihao"] 和nums[5]的内存地址不一样,列表是可变数据类型,内存地址不一样
c[0] 和 nums[5][0] 的内存地址一样

因为:数据一旦存在,就会被定义进常量区,在任意引用使用的时候直接赋值内存地址,因为不可变数据类型的对象数据不会发生变化,没有必要声明成两个一样的数据放在两个区

ex:
if [1][0]:
print("hello")
else:
print("world")
最后会执行hello,因为 [1][0]:前面的[1]是列表,后面的[0]是取列表的第一个单位索引,也就是1,TRUE

一般情况下,可变类型的对象会创建在堆内存中,不可变类型会创建在常量区

需要创建对象时,先在常量区中找,有没有这个常量,有的话就不需要创建,没有的话需要在堆内存区创建,然后拿到常量区使用

ex:
a = "hello" 在内存中会创建几块内存空间 2个(a:栈内存,hello:常量内存)
p = Person("tom",19) 在内存中会创建几块内存空间 4个(p:栈内存,tom,19:常量区,Person obj:堆内存)

内存检测模块:memory profile
测试内存:在测试函数前面,添加一个检测注解@profile
最小测试单位是函数|方法

操作符号:is 和 == 的 使用 isinstance
操作符号用于判断对象和对象之间的关系。

跟对象内存相关的三个操作符号
a = 1000
b = 1000 (在命令交互行)
is :a is b ->判断两个变量a/b,他们指向的对象是否同一个对象
class Person()
==:a==b ->判断两个变量a/b,他们指向的对象的数据内容是否一致,内存指向的地址是否一致,【不做深层判断】一致 TRUE
isinstance(a,b):判断a对象是否属于b类型

拷贝->浅拷贝,深拷贝
都创建了一个新的对象,内存地址都不一样
浅拷贝->x = copy.copy(a) 拷贝a的引用,不拷贝数据,复制一个对象,复制对象中的属性数据的引用
临时备份,核心是赋值对象内部数据的引用
x 和 a 的引用是一样的,是同一个数据的内存,修改拷贝的对象的数据,对象的数据也会修改

深拷贝->x = copy.deepcopy(a) 拷贝a的所有数据,而不是引用,等于说是把对象的数据拷贝走了一份,拷贝走的数据就属于拷贝好的对象使用,不互相影响

->如果程序中多个不同的地方都要使用同一个对象,通过对象的引用赋值,将同一个对象赋值给多个变量
->如果程序中多个不同的地方都要使用相同的数据对象,通过对象的拷贝完成数据的简单复制即可,对象中的包含的数据要求必须统一(索引)
->如果程序中多个不同的地方使用相同的而且独立的对象数据,通过对象的深层次的复制,将对象的数据完整复制成独立的另一份即可

垃圾回收机制
what:现阶段任何高级语言的特性,针对程序运行过程中,出现的垃圾数据进行自动回收,自动回收无效对象数据,通过垃圾回收算法进行操作 Garbage Collention:GC
在一定程度上,能优化编程语言的数据处理效率和提高编程软件开发软件的安全性能
遵循垃圾回收算法
python中,以引用计数垃圾回收算法为主要回收机制
以标记-清除 和 分代回收 为辅助回收机制

sys.getrefcount(p) ->查询指定对象的引用数量

引用计数算法的原理:python中所有的对象|类型,都是直接或间接继承自object
object对象底层是C语言的一个结构体!

->引用计数
核心思想:当一个对象被创建或者拷贝时,引用计数就会+1,当这个对象的多个引用变量被销毁一个时,引用计数就会-1,如果一个对象的引用计数为0,则表示该对象已经不被引用,就可以让垃圾回收机制进行清除并释放该对象占有的内存空间
优点:操作简单,实时性能优秀,能在最短的时间获得并运算对象的引用数
缺点:消耗内存和对象的内存对等,增加内存负担,同时对于循环应用/对象之间的互相引用,是无法进行引用计数的,所以就会造成常驻内存的情况

->标记清除

主要是针对可能产生循环引用的对象进行的检测机制,一般循环引用总是发生list,dict,class等可变对象的内部属性中,使得该方法消耗的资源和程序中可变对象的数量息息相关

核心思想:首先找到PYTHON中的一批根节点对象,如object对象,通过根节点对象可以找到他们指向的子节点对象,如果搜索过程中有这个指向是从上往下的指向,表示这个对象是可达的,否则该对象是不可达的,可达部分的对象在程序中需要保留下来,不可达部分的对象在程序中是不需要保留的,清除

->分代回收
pytho中的分代回收机制,是一种通过空间换取时间效率的做法,python内部处理机制定义了三个不同的链表数据结构(年轻代),第1代(中年代),第二代(老年代)python为了提高程序执行效率,将垃圾回收机制进行了阈值限定,0代链表中的垃圾回收机制执行最为紧密,其次是1代,最后是2代

python定义这三个链表,主要是针对我们在程序中创建的对象,首先会添加到0代链表,随后0代链表数量达到一定的阈值之后,触发GC算法机制,对0代对象进行符合规则的引用计数运算,避免出现对象的延迟或者过早的释放,最终,触发GC机制将已经没有引用指向的对象进行回收,并将有引用指向的对象移动到第1代对象链表中,第1代对象链表的对象,就是比第0代对象链表中的对象可能存活更久的对象,GC阈值更大,检测频率更慢,以提高程序执行效率,以此类推到一部分对象存活在第2代对象链表中,对象周期较长的可能跟程序的生命周期一样。

弱代假说:程序中年轻的对象 往往死的更快,年老的对象往往存活更久。

                                                                      我是一只小菜鸟:WDJ

相关文章

  • python基础->内存分析和处理->垃圾回收机制

    内存分析和处理 why:为什么要进行内存分析和处理?软件->一个完整的软件加载运行流程->基于硬件软件:处理数据-...

  • python拾遗7 - 垃圾回收

    垃圾回收机制 相比 C++ 的手动回收内存,python 的垃圾回收机制可谓是省心省力,判断是否回收一块内存,主要...

  • python必知必会12

    Python 的内存机制 内存机制主要包括垃圾收集和内存管理两部分。Python 主要使用基于引用计数的垃圾回收机...

  • python学习一

    1 python 如何管理内存 对象引用计数机制,垃圾回收机制,内存池机制 一。对象引用机制 python内部引用...

  • python内存管理机制

    Python内存管理机制 Python内存管理机制主要包括以下三个方面: 引用计数机制 垃圾回收机制 内存池机制 ...

  • 【Android】知识点汇总,坚持原创ing

    Android基础 Java基础 Java基础——Java内存模型和垃圾回收机制 语法基础 语法基础——C语法基础...

  • python替换转义字符

    python字符串处理有时候会出现< >&" 等转义字符HTML的< >...

  • python的GC

    python垃圾回收机制 Python GC 主要是引用计数来跟踪和回收垃圾。 在引用技数的基础上, 通过"标记-...

  • Python内存管理机制

    Python内存管理机制主要包括以下三个方面:引用计数机制 垃圾回收机制 内存池机制

  • 2018-11-19 python学习第三天

    1、内存回收机制: 在其他语言中需要考虑内存回收机制,垃圾数据太多会导致内存溢出。但是python语言无需考虑这点...

网友评论

      本文标题:python基础->内存分析和处理->垃圾回收机制

      本文链接:https://www.haomeiwen.com/subject/hpsuiftx.html