python进阶之内存模型
每一个编程语言的背后都有自己独特的内存模型支持,比如最经典的C语言,一个int类型占8字节。那么在python中不区分数据类型,定义一个变量其在内存在占用多少字节呢?python中数据的运算其内存是如何变化的呢?
在回答上面的问题之前,首先看一下python中可变的数据和不可变数据
一、可变对象和不可变对象
Python一切数据皆为对象,python中的对象分成两类:可变对象和不可变对象。所谓可变对象是指,对象的内容可变,而不可变对象是指对象内容不可变。
不可变(immutable):数值(int、float)、字符串(string)、元组(tuple)
可变(mutable):字典型(dictionary)、列表型(list)
根据对象的分类,可以将数据类型也做一个分类,可变数据类型与不可变数据类型:
可变数据类型:列表list和字典dict
不可变数据类型:整型int、浮点型float、字符串型string和元组tuple
这里的可变不可变,是指内存中的那块内容是否可以被改变。
如果是不可变类型,在对对象本身操作的时候,必须在内存中新申请一块区域(因为老区域不可变)。创建a=1整型对象,执行a=2时,内存中的对象1是不变的,只是重新创建了对象2。
如果是可变类型,对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连续申请(+/-)即可,也就是它的内存地址会保持不变,但区域会变长或者变短。
当对可变和不可变对象运算时会内存中会发生什么事情呢?对比来看
不可变数据类型:不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;
可变数据类型:允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。
python对于数据的特殊处理
小整数
Python为了优化速度,避免为整数频繁申请和销毁内存空间,使用了小整数对象池。对小整数的定义是 [-5, 256] 这些整数对象是提前建立好的,不会被垃圾回收。在这个范围内所有的整数都只会被建立一次。
a =
b =
print(id(a))
print(id(b)) -------------------------
a =
b = print a is b
-----------------
True a =
b =
print a is b
-----------------
False
大整数
大整数池: 只存储包含标准字符(数字、字母、下划线)的字符串,不包含特殊字符的字符串 。
python为了避免创建大整数浪费的内存空间和时间,将创建过的大整数加入大整数池。
python中大整数池,默认大整数池里面为空,每一个py程序都有一个大整数池。使用大整数时如果大整数池里不存在该整数的话,会新建一个大整数对象。下次使用大整数时直接使用大整数池里的对象,而不是创建新的对象
py文件中,每次运行时都会将所有代码加载到内存中,属于一个整体,因此处于同一个代码块的大整数是同一个对象,所以两者id是一样的。
a = ''
b = '' print id(a)
print id(b)
----------------------------- print a is b
-----------------------------
True
其他数据类型
如果是其他普通类型对象的新建,python会请求内存,申请内存 。当n1的引用指向其他对象时,原有对象的引用计数会自动减1,没有被引用的对象会立即回收。
python进阶之内存模型的更多相关文章
- Swift进阶之内存模型和方法调度
前言 Apple今年推出了Swift3.0,较2.3来说,3.0是一次重大的升级.关于这次更新,在这里都可以找到,最主要的还是提高了Swift的性能,优化了Swift API的设计(命名)规范. 前段 ...
- Swift 对象内存模型探究(一)
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/zIkB9KnAt1YPWGOOwyqY3Q 作者:王 ...
- python变量的内存机制
python变量的内存机制 作为一门简单易用的语言,且配备海量的库,python可谓是程序员手中的掌中宝,编程本身就是一种将人类思维转化为计算机思维的技术,如果不需要去追求极致的运行效率同时又不限制于 ...
- Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型
Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: 每个对象都对应于一个可称为" 互斥锁&qu ...
- Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)
Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: 将一些东西封装到一个地方,你还可以取出来( ...
- python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
python Django教程 之 模型(数据库).自定义Field.数据表更改.QuerySet API 一.Django 模型(数据库) Django 模型是与数据库相关的,与数据库相关的代码 ...
- Python进阶 - 对象,名字以及绑定
Python进阶 - 对象,名字以及绑定 1.一切皆对象 Python哲学: Python中一切皆对象 1.1 数据模型-对象,值以及类型 对象是Python对数据的抽象.Python程序中所有的数据 ...
- Python进阶----数据库的基础,关系型数据库与非关系型数据库(No SQL:not only sql),mysql数据库语言基础(增删改查,权限设定)
day37 一丶Python进阶----数据库的基础,mysql数据库语言基础(增删改查,权限设定) 什么是数据库: 简称:DataBase ---->DB 数据库即存放数据的仓库, ...
- Python进阶(十三)----面向对象
Python进阶(十三)----面向对象 一丶面向过程编程vs函数式编程vs面向对象编程 面向过程: 简而言之,step by step 一步一步完成功能,就是分析出解决问题所需要的步骤,然后用函 ...
随机推荐
- 搭建ES集群
服务版本选择 TEG的ctsdb当前最高版本采用的是es的6.4.3版本,为了日后与ctsdb衔接方便,部署开源版es时也采用该版本.6.4.3版本的es依赖的jdk版本要求在8u181以上,测试环境 ...
- 46.QT-自带库QSerialPort串口使用
之前一章学习的是第三方库使用: 34.QT-qextserialport第三方库制作串口助手(并动态检测在线串口,附带源码) 本章来学习自带serial库 1.QSerialPortInfo QLis ...
- Linux学习入门-------------------------VMvare与镜像的安装与配置
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/qq_39038465/article/d ...
- sqlplus登录时密码有特殊符号解决方法
偶然百度得到解决方法,在查看了公司有的脚本使用了这种解决方式,特记录下来,有需要的可以点击文末的链接查看原文. 本文转载https://www.cnblogs.com/lhrbest/p/656090 ...
- 表单生成器(Form Builder)之mongodb表单数据查询——关联查询
这一篇接着记录一下查询相关的操作.想象一下,如果想要在一张表格中展示某些车辆的耗损和营收情况,我们该怎么处理.车辆.耗损.营收各自存储在一张表中,耗损和营收中冗余了车辆信息……我们便想到了关联查询.m ...
- Iris入门操练1
选一个框架,慢慢熟悉··· 按官网文档,先走一次.. package main import ( "github.com/kataras/iris/v12" "githu ...
- 【问题篇四】启动报DataSource错误
初建一个简单的spring boot 项目,启动后会报错:就是在项目启动的时候在 resource目录下没有加载到配置信息:如果项目只是想简单的启动运行,不进行数据库操作可以在 启动类上做如下处理便可 ...
- java之父类中的构造器是否能被子类继承?
子类默认继承父类的属性和方法,但不会继承父类的构造器,而是在子类被实例化时会默认调用父类的空构造器.子类在创建的时候会调用自己的空构造器,并在空构造器会隐式调用super(),即父类的空构造器.如果父 ...
- SpringBoot源码学习系列之@PropertySource不支持yaml读取原因
然后,为什么@PropertySource注解默认不支持?可以简单跟一下源码 @PropertySource源码: 根据注释,默认使用DefaultPropertySourceFactory类作为资源 ...
- 为什么 Go 标准库中有些函数只有签名,没有函数体?
如果你看过 Go 语言标准库,应该有见到过,有一些函数只有签名,没有函数体.你有没有感觉到很奇怪?这到底是怎么回事?我们自己可以这么做吗?本文就来解密它. 首先,函数肯定得有实现,没有函数体,一定是在 ...