程序内存浅析
硬盘:数据永久存储的地方
内存条:数据临时存储的地方
cup寄存器:数据运算时临时存储的地方
软件:一个完整的软件加载运行流程—》基于硬件
处理数据》数据硬件中的数据》硬件(读|存)》内存(读|存)》缓存(运算)
内存中的数据,决定了一个正在运行的软件的数据处理过程
当一个软件运行时,优先向系统内存空间加载软件处理数据
软件两种状态:执行状态(等待) 运行状态(运算)
python程序运行过程中,主要是解释器从系统中申请内存空间以运行python软件
解释器将申请的内存主要区分这样几个部分用于处理执行的程序软件
|
栈内存去stack |
堆内存去heap |
|
静态区|常量区static |
|
|
方法区|数据区data |
|
|
栈内存区[stack]:用于直接分配数据,存取速度较快,数据存储不稳定,适用于小数据 块的快速存取,一般在程序中用于存储变量数据 |
|
|
方法区[data]:主要用于加载程序中使用的代码数据、二进制数据、方法数据等等程序 运行需要的预加载数据 |
|
|
静态区[static]:主要用于加载存储程序中的一些静态数据、常量数据等等,在 PYTHON 中的不可变数据类型的数据,也会存储在静态常量区内存中 |
|
|
堆内存[heap]:存储数据稳定持久,一般用于存储加载较为重量级的数据,如程序运行 过程中的对象都是存在堆内存中的 |
|
程序变量和对象的基本操作
- 不可变数据类型 和 和可变数据类型
不可变数据类型:一般基本数据类型都是不可变数据类型 内存地址中存储的数据可变
可变数据类型:一般组合数据类型或者自定义数据类都是可变数据类型 内存地址中存储的数据不能变化
- 如何区分可变和不可变
python中的一切都是对象,可以通过id()函数查询对象在内存中的地址数据
可变数据类型是在定义了数据之后,修改变量的数据,内存地址不会发生变化
不可变数据类型是定义了数据之后,修改变量的数据,变量不会修改原来的内存地址的数据而是会指向新的地址,原有数据保留,这样更加方便程序的基本数据的利用率
代码和代码块
python中的最小运行单元是代码块,代码块的最小单元是一行代码
python的两种操作模式
交互模式
一行命令就是一个代码块
Ide模式()
在交互模式下,每行命令是一个独立运行的代码块,每个代码块运行会独立申请一次内存
但是在 IDE 开发模式下,代码封装在模块中,通过 python 命令运行模块时,模块整体作为 一个代码块向系统申请内存并执行程序,执行过程中对于基本数据类型进行缓存优化操作,
不可变类型,在同一个代码块中进行多次使用时会将该类型的对象,直接创建在常量区任意引用时直接赋值内存地址
If后第一个为列表第二个为索引
一般情况下可变类型的对象会创建在堆内存中,不可变类型对象会创建在常量区内存中

程序中的内存检测
通过pip工具安装
Pip install memory_profiler
通过在测试的函数或者类型等前面添加@profile 注解,让内存分析模块可以直接进行代码 运行检测
From memory_profile import profile
@profile
@profile
@memory_profiler.profile最小检测单元为函数
操作符号:is和==的使用
如何判断对象和对象之间的关系
对象操作符号is
内容操作符号 ==
A is B:判断对象 A 和对象 B 是否同一个内存地址,即是否同一个对象
A == B:判断 A 中的内容是否和 B 中的内容一致
Isinstance()类型判断
Isinstance(p1,proson)判断p1是否为该类型
引用、浅拷贝、深拷贝
栈内存先进后出后进先出
- 上图问题的解决
问题一:两个变量指向同一个对象
1.对象的引用赋值 :将同一个对象的引用,赋值给多个变量
多个变量,指向同一个对象
是将自己的地址赋值个多个变量,通过多个变量可以操纵一个对象
Class Person:
def __init__(self, name, fav)
Self..name = name
Self.sav = [“篮球”, “足球”,”排球”]
a = Person(“tom”,[“lol”, “ow”])
b = c = a
print(id(b), id(c), id(a))
该程序输出的结果都为同一个地址
问题二:如何复制对象
- 浅拷贝 :只拷贝对象中的引用
- 深拷贝: 拷贝对象属性的数据
根据上边的代码继续
# 对象的浅拷贝,复制对象中的属性数据的引用
X = copy.copy(a) # 拷贝a对象,产生了一个x对象
x.fav.append(“pubg”)# 在列表中添加一个数据
x.name = “jerry”
列表可变的 字符串不可变的
即name的值不相同,fav列表中的数据相同
#对象的深拷贝:拷贝创建一个新对象,同时拷贝对象属性的数据
Y = copy.deepcopy(a)
y.name = “jerry”
y.fav.append(“ow”)
由于深拷贝是连数据一块拷贝的 所以在修改数据是不会对原数据产生任何影响