初入python

内存简析(上)

2018-08-23  本文已影响0人  言烬

程序在运行需要将数据加载到内存中,然后通过CPU进行内存数据的读写完成数据的运算。

内存浅析:

软件程序在程序中的执行,主要是通过数据单元、控制单元、执行单元共同协作,完成数据的交互,达到程序处理数据的目的。

在软件执行的过程,由于系统内存和CPU的资源非常有限,所以有效的分解软件中的各项数据,将不同数据加载到不同的内存部分以有效的运行程序,同时可以达到在计算机中有效的运行更多软件的目的。

持久化:在一个可以永久存储数据的地方进行数据的读取和存储

图解:

图片1.png

python程序在运行的过程中主要是解释器从系统中申请内存空间以运行python软件。

python解释器将申请到的内存主要分成四个部分:

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

栈内存区:用于直接分配数据,存取速度较快,数据存储不稳定,适合用于小数据块的快速存取,常用于存储“变量”

堆内存区:用于加载程序中使用的代码数据,二进制数据,方法数据等等程序运行需要的预加载数据,存取速度较慢,比较消耗资源,但只要数据存在,数据操作比较稳定。常用于存储“对象”

静态储存区|常量区:专门存放程序中的公共数据,静态数据的内存区域

方法区|数据区:专门加载程序运行的代码字节数据,方法数据,函数数据等等

图解:

图片2.png

内存分配基础代码:


图片7.png

图解代码:

图片3.png

不可变数据类型与可变数据类型

python中根据数据是否可以进行修改提供了两种不同的数据类型

不可变数据类型:一般基本数据类型都是不可变数据类型,对象在内存地址中存储的数据可变。例如:b = 12

整数类型:-5 ~ 255在解释器加载时,常量区已经自动分配好了这些数字的内存地址

超出这个数字的范围,在一个代码块中申请一次内存

交互模式下一行代码就是一个代码块

开发工具下一个模块就是一个代码块

不可变类型在同一个代码块中进行多次使用时,会将该类型的对象,直接创建在常量区,在任意引用的时候直接赋值内存地址,因为不可变类型的对象数据不会发生变化,所以内存中存储一份即可!用于优化程序执行效率

可变数据类型:一般组合数据类型或者自定义数据类型都是可变数据类型,对象在内存地址中存储的数据不可变。例如:a = list()

一般情况下,可变类型的对象会直接创建在堆内存中

不可变类型的对象会创建在常量区内存中

关于字符串:因为字符串使用的频率较高,为了提高程序运行效率,会优先优化字符串

如果要创建一个字符串对象,程序会先到常量区里寻找这个字符串,如果常量区里存在这个字符串,直接取出来赋值给变量。如果没有,创建一个赋值给变量,这样在下一次使用的时候,程序先在常量区里寻找,然后直接赋值。这个字符串对象不会删除

思考题:

# 思考题:
nums = [12, 13, 15, 18, 20, "hello", ["world", "python"]]

a = 20  #  nums[4] 是否同一个内存地址? 是!
print(id(a), id(nums[4]))

b = "hello"# nums[5] 是否同一个内存地址?是
print(id(b), id(nums[5]))

c = ["world", "python"] # nums[6] 是否同一个内存地址 否
print(id(c), id(nums[6]))

print(id(nums[6][0]), id(c[0])) # 两个列表中的world字符串 是

试题:

# 奇怪的语法
if [1][0]:
    print("hello")
else:
    print("world")

解释:这个语法中,[1]是一个列表,[0]代表的是索引,1代表True,所以输出hello

精确控制数据:

试题:

def chg_nums(n):
    n = 20


def chg_list(l):
    l.append(20)


a = 18
chg_nums(a)

b = [1,2]
chg_list(b)

print(a) # ?18        20                18             20
print(b) # ?[1,2]     [1,2,20]          [1,2,20]       [1,2]

输出结果:

图片6.png

解释:a,n原本都等于18,经过函数chg_nums(),n被赋值为20,但a仍然是18,所以a仍然等于18。

b是一个列表[1,2], 经过调用函数chg_list(), 出现一个新的变量l, l仍指向列表[1,2], 因为函数中l增加了一个数字20,所以l变成了[1,2,20], 即列表变成了[1,2,20],所以b输出[1,2,20]

图片4.png 图片5.png

如有错误,敬请指出

上一篇下一篇

猜你喜欢

热点阅读