1内存分析和处理
.程序的运行离不开对内存的操作,一个软件要运行,需要将数据加载到内存中,通过CPU进行内存数据的读写,完成数据的运算。
2.程序内存浅析
软件程序在计算机中的执行,主要是通过数据单元、控制单元、执行单元共同协作,完成数据的焦距,达到程序处理数据的目的,在软件执行的过程中,由于系统内存和CPU的资源非常有限,所以有效的分解软件中的各项数据,将不同的数据加载到不同的内存部分以有效的运行程序,同时可以达到在一个计算机中有效运行更多软件的目的
python程序在运行过程中国,主要是解释器从系统中申请内存空间以运行python软件解释器将申请的内存主要区分为这样几个部分用于处理执行的程序软件
(1)栈内存区【stack】:用于直接分配数据,存取速度较快,数据存储不稳定,适用于小数据快的快速存取,一般在程序中国用于存储变量数据
堆内存区【heap】:存储数据稳定持久,一般用于存储加载较为重量级的数据,如程序运行过程中的对象都是存在堆内存中的
静态区|常量区【static】:主要用于加载存储程序中的一些静态数据、常量数据等等,在python中的不可变数据类型的数据,也会存储在静态常量区内存中
方法区|数据区【data】主要用于加载程序中使用的代码数据、二进制数据、方法数据等等程序运行需要的预加载数据
程序中变量和对象的基本表示方式
程序中有一个类型Hero,我们在代码中创建了一个Hero对象,将对象那个的值赋值给一个变量hero,内存中内存信息的分配如下:
2.1 不可变数据类型 vs 可变数据类型
python中根据数据是否可以进行修改提供了两种不同的数据类型
(1) 不可变数据类型— :一般基本数据类型都是不可变数据类型
(2)可变数据类型—: 一般组合数据类型或者自定义数据类都是可变数据类型
怎么区分可变和不可变?为什么要有这样的规则?
pyhton中的一切都是对象,可以通过id()函数查询对象在内存中的地址数据
可变数据类型是在定义了数据之后,修改变量的数据,内存地址不会发生变化
不可变数据类型时在定义了数据之后,修改变量的数据,变量不会修改原来内存地址的数据而是会指向新的地址,原有的数据保留,这样更加方便程序中基本数据的利用率
2.2 代码和代码块
python中的最小运行单元是代码块,代码块的最小单元是一行代码
在实际开发过程中,需要注意的是python有两种操作方式
(1) 交互模式
(2)IDE开发模式
在交互模式下,每行命令是一个独立运行的代码块,每个代码块运行会独立申请一次内存,在操作工程中交互模式没有退出的情况下遵循pyhton官方操作标准
如:对基本数据类型进行了基本优化操作,将一定范围内的数据存储在常量区以提升性能
在交互模式下运行:
>>>a = 12
>>>b = 12
4426725056
>>>id(b)
4426725056
-5到256之间的数据自动缓存
>>>a = "hello""
>>>b = "hello"
>>>id(a)
4430210920
>>>id(b)
4430210920
字符串自动缓存
>>>a = 1000
>>>b = 1000
>>>id(a)
4429864720
>>>id(b)
4429864752
超出范围的数据重新申请内存
但是在IDE开发模式下,代码封装在模块中,通过pyhton命令运行模块时,模块整体作为一个代码块向系统申请内存并执行程序,执行过程中对于基本数据类型进行缓存优化操作,通过pycharm工具执行上述代码测试:
a = 12
b = 12
pritn(id(a),id(b))
a = "hello"
b = "hello"
print(id(a),id(b))
a = 1000
b = 1000
print(id(a),id(b))
4338726592 4338726592
4341200016 4341200016
4339572432 4339572432
2.3 程序内存代码检测
python对于内存的操作,社区开发了一款比较强大的专门用于检测代码内存使用率,用于项目代码调优的模块memory_profile 是一个使用较为简单,并且可视化比较直观的工具模块,通过pip工具安装即可使用
pip install memory_profiler
通过在测试的函数或者类型等前面添加@profile注解,让内存分析模块可以直接进行diamante运行检测,代码如下: