python可变类型和不可变类型,内存管理

python可变类型和不可变类型,内存管理

1. python中创建可变对象和不可变对象时的内存分配

首先看两个简单创建可变对象和不可变对象的例子:

a = 1, b = 1
a和b的id是否相等?
a = 1000, b = 1000
a和b的id是否相等?
a = ‘a’, b = ‘a’
a和b的id是否相等?
a = (1,) b=(1, )
a和b的id是否相等?
a=[1], b=[1]
a和b的id是否相等?

在notebook中测试如下:
代码测试
从结果中可以看到:

  • 对于小整数其在解释器加载的时候就已经为其分配了内存,其内存地址都是相等的,但对于超过该范围的就要创建对象的时候申请内存空间,其id是不一样的;
  • 对于小字符串,其创建的对象不会申请两个内存地址,对于复杂一点的字符串,在创建的时候会重写申请内存地址
  • 对于元组和列表对象,不管位数如何其内存地址都是不一样的,其在创建对象的时候都会新申请一个内存地址

总结: 在python中不管是创建两个相同的可变对象和不可变对象,其都要向解释器申请内存空间,其id是不一样的;但是python对于一些整数类型(-5~256)和小字符串类型的对象做了优化,其在解释器加载的时候就已经分配了内存,在创建对象的时候只要为该对象增加一个引用即可,所以id是一样的;而对于变量赋值,只是给对象增加了一个引用,其内存地址肯定是一样的.

再看一个下面的例子:
nums = [12, 13, 15, 18, 20, "hello", ["world", "python"], (1, 2)]

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

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

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

print(nums[6][0] is c[0])
# 两个列表中的world字符串是否相同?

d = (1, 2)
# nums[7] 和d是否同一个内存地址?
print(d is nums[7])

结果如下:

True
True
False
True
False

可以看到对于小的字符串和整数其都指向同一个内存地址,而对于列表和元组则新分配了一个内存地址

2.程序执行

一个软件程序要想执行,必须要先把硬盘上所需的数据加载到内存中,cup再去内存中取程序执行的数据进行运算和处理,如下图:
在这里插入图片描述

程序运行时内存分配:
软件的程序在计算机中的执行,主要是通过数据单元、控制单元、执行单元共同协作,完成数据的交互达到程序处理数据的目的,在软件的执行过程中,由于系统内存和CPU的资源有限,所以有效的分解软件中的各项数据,将不同的数据加载到不同的内存部分以有效的运行程序,同时可以达到在一个计算机中有效运行更多软件的目的;内存中主要包括以下几个内存区:

  • 栈内存区: 该区主要存放变量对象及其引用,存取速度较快,适用于小数据的快速存储
  • 方法区:主要用于存放加载程序需要的代码数据,二进制数据,方法和函数数据等
  • 静态资源(常量区):主要存储静态数据,常量数据;对于python中的不可变对象一般也会存储在该内存区.
  • 堆内存区:该区主要存放对象数据和类型,存储数据稳定,一般存储较为重要的数据;对于python中的可变对象一般会存储到该区

如下图:
在这里插入图片描述

3.python 中的可变和不可变对象

可变对象:当可变对象中的元素发生改变如重新赋值,该对象的内存地址不会发生改变;如列表,字典,集合
不可变对象:当可变对象中的元素发生改变,该对象的内存地址也会改变,即重新创建了一个内存空间来存放新数据;如数值类型,字符串,元组.

4.python 中的内存申请

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

python中的内存管理机制–pymalloc: python内存管理机制都有两套实现方法,第一是针对小对象,小于256bits时,pymalloc会直接在内存池中申请内存空间;当大于256bits,则会直接执行new/malloc的行为申请内存空间;这样可以防止频繁调用系统的new/malloc来创建和销毁小对象.

python中的内存释放: 垃圾回收机制.

参考文档:
https://www.jianshu.com/p/2f98dd213f04

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值