浅谈Python 对象内存占用


Posted in Python onJuly 15, 2016

一切皆是对象

在 Python 一切皆是对象,包括所有类型的常量与变量,整型,布尔型,甚至函数。 参见stackoverflow上的一个问题 Is everything an object in python like ruby

代码中即可以验证:

# everythin in python is object def fuction(): return print isinstance(True, object) print isinstance(0, object) print isinstance('a', object) print isinstance(fuction, object)

如何计算

Python 在 sys 模块中提供函数 getsizeof 来计算 Python 对象的大小。

sys.getsizeof(object[, default])

以字节(byte)为单位返回对象大小。 这个对象可以是任何类型的对象。 所以内置对象都能返回正确的结果 但不保证对第三方扩展有效,因为和具体实现相关。

......

getsizeof() 调用对象的 __sizeof__ 方法, 如果对象由垃圾收集器管理, 则会加上额外的垃圾收集器开销。

当然,对象内存占用与 Python 版本以及操作系统版本关系密切, 本文的代码和测试结果都是基于 windows7 32位操作系统。

import sys print sys.version

2.7.2 (default, Jun 24 2011, 12:21:10) [MSC v.1500 32 bit (Intel)]

基本类型

•布尔型

print 'size of True: %d' % (sys.getsizeof(True)) print 'size of False: %d' % (sys.getsizeof(False))

输出:

size of True: 12 size of False: 12

•整型

# normal integer print 'size of integer: %d' % (sys.getsizeof(1)) # long print 'size of long integer: %d' % (sys.getsizeof(1L)) print 'size of big long integer: %d' % (sys.getsizeof(100000L)) 输出:

size of integer: 12x size of long integer 1L: 14 size of long integer 100000L: 16

可以看出整型占用12字节,长整型最少占用14字节,且占用空间会随着位数的增多而变大。 在2.x版本,如果整型类型的值超出sys.maxint,则自动会扩展为长整型。而 Python 3.0 之后,整型和长整型统一为一种类型。

•浮点型

print 'size of float: %d' % (sys.getsizeof(1.0))

输出:

size of float: 16

浮点型占用16个字节。超过一定精度后会四舍五入。

参考如下代码:

print 1.00000000003 print 1.000000000005

输出:

1.00000000003 1.00000000001

•字符串

# size of string type print '\r\n'.join(["size of string with %d chars: %d" % (len(elem), sys.getsizeof(elem)) for elem in ["", "a", "ab"]]) # size of unicode string print '\r\n'.join(["size of unicode string with %d chars: %d" % (len(elem), sys.getsizeof(elem)) for elem in [u"", u"a", u"ab"]])

输出:

size of string with 0 chars: 21 size of string with 1 chars: 22 size of string with 2 chars: 23 size of unicode string with 0 chars: 26 size of unicode string with 1 chars: 28 size of unicode string with 2 chars: 30

普通空字符串占21个字节,每增加一个字符,多占用1个字节。Unicode字符串最少占用26个字节,每增加一个字符,多占用2个字节。

集合类型

•列表

# size of list type print '\r\n'.join(["size of list with %d elements: %d" % (len(elem), sys.getsizeof(elem)) for elem in [[], [0], [0,2], [0,1,2]]])

输出:

size of list with 0 elements: 36 size of list with 1 elements: 40 size of list with 2 elements: 44 size of list with 3 elements: 48

可见列表最少占用36个字节,每增加一个元素,增加4个字节。但要注意,sys.getsizeof 函数并不计算容器类型的元素大小。比如:

print 'size of list with 3 integers %d' % (sys.getsizeof([0,1,2])) print 'size of list with 3 strings %d' % (sys.getsizeof(['0','1','2']))

输出:

size of list with 3 integers 48 size of list with 3 strings 48

容器中保存的应该是对元素的引用。如果要准确计算容器,可以参考recursive sizeof recipe 。使用其给出的 total_size 函数:

print 'total size of list with 3 integers %d' % (total_size([0,1,2])) print 'total size of list with 3 strings %d' % (total_size(['0','1','2']))

输出为:

total size of list with 3 integers 84 total size of list with 3 strings 114

可以看出列表的空间占用为 基本空间 36 + (对象引用 4 + 对象大小) * 元素个数。

另外还需注意如果声明一个列表变量,则其会预先分配一些空间,以便添加元素时增加效率:

li = [] for i in range(0, 101): print 'list with %d integers size: %d, total_size: %d' % (i, getsizeof(li), total_size(li)) li.append(i)

•元组

基本与列表类似,但其最少占用为28个字节。

•字典

字典的情况相对复杂很多,具体当然要参考代码 dictobject.c, 另外 NOTES ON OPTIMIZING DICTIONARIES 非常值得仔细阅读。

基本情况可以参考[stackoverflow] 的问题 Python's underlying hash data structure for dictionaries 中的一些回答:

•字典最小拥有8个条目的空间(PyDict_MINSIZE);
•条目数小于50,000时,每次增长4倍;
•条目数大于50,000时,每次增长2倍;
•键的hash值缓存在字典中,字典调整大小后不会重新计算;

每接近2/3时,字典会调整大小。

以上这篇浅谈Python 对象内存占用就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python创建日历实例
Aug 21 Python
使用简单工厂模式来进行Python的设计模式编程
Mar 01 Python
20招让你的Python飞起来!
Sep 27 Python
Python中asyncio模块的深入讲解
Jun 10 Python
Django 后台获取文件列表 InMemoryUploadedFile的例子
Aug 07 Python
python实现把二维列表变为一维列表的方法分析
Oct 08 Python
Python线程指南分享
Nov 19 Python
使用 Supervisor 监控 Python3 进程方式
Dec 05 Python
Django对接支付宝实现支付宝充值金币功能示例
Dec 17 Python
在pycharm中关掉ipython console/PyDev操作
Jun 09 Python
python的launcher用法知识点总结
Aug 07 Python
如何用Python进行时间序列分解和预测
Mar 01 Python
python发送邮件功能实现代码
Jul 15 #Python
Python中列表和元组的使用方法和区别详解
Dec 30 #Python
Python中的变量和作用域详解
Jul 13 #Python
在Python中通过threading模块定义和调用线程的方法
Jul 12 #Python
举例讲解Python编程中对线程锁的使用
Jul 12 #Python
使用Python编写一个最基础的代码解释器的要点解析
Jul 12 #Python
Python中使用bidict模块双向字典结构的奇技淫巧
Jul 12 #Python
You might like
PHP保留两位小数并且四舍五入及不四舍五入的方法
2013/09/22 PHP
php中{}大括号是什么意思
2013/12/01 PHP
ThinkPHP中使用ajax接收json数据的方法
2014/12/18 PHP
PHP输出一个等腰三角形的方法
2015/05/12 PHP
PHP可变变量学习小结
2015/11/29 PHP
PHP函数shuffle()取数组若干个随机元素的方法分析
2016/04/02 PHP
浅谈Laravel核心解读之Console内核
2018/12/02 PHP
使用新的消息弹出框blackbirdjs
2008/10/16 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
2014/10/29 Javascript
21个JavaScript事件(Events)属性汇总
2014/12/02 Javascript
JavaScript数组各种常见用法实例分析
2015/08/04 Javascript
jQuery版AJAX简易封装代码
2016/09/14 Javascript
一个极为简单的requirejs实现方法
2016/10/20 Javascript
js模式化窗口问题![window.dialogArguments]
2016/10/30 Javascript
vue双向数据绑定原理探究(附demo)
2017/01/17 Javascript
Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法
2017/09/20 Javascript
vue 实现复制内容到粘贴板clipboard的方法
2018/03/17 Javascript
Vue 使用 Mint UI 实现左滑删除效果CellSwipe
2018/04/27 Javascript
微信小程序导入Vant报错VM292:1 thirdScriptError的解决方法
2019/08/01 Javascript
extjs4图表绘制之折线图实现方法分析
2020/03/06 Javascript
[01:37]DOTA2超级联赛专访ChuaN 传奇般的电竞之路
2013/06/19 DOTA
深入讲解Java编程中类的生命周期
2016/02/05 Python
Python正则表达式教程之一:基础篇
2017/03/02 Python
Python实现矩阵转置的方法分析
2017/11/24 Python
Python实现屏幕截图的两种方式
2018/02/05 Python
python3 判断列表是一个空列表的方法
2018/05/04 Python
对Python subprocess.Popen子进程管道阻塞详解
2018/10/29 Python
Python/Django后端使用PIL Image生成头像缩略图
2019/04/30 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
2020/02/10 Python
IE下实现类似CSS3 text-shadow文字阴影的几种方法
2011/05/11 HTML / CSS
简单介绍HTML5中的文件导入
2015/05/08 HTML / CSS
HTML5语义化元素你真的用对了吗
2019/08/22 HTML / CSS
上海世博会志愿者口号
2014/06/17 职场文书
村长反四风问题个人对照检查材料
2014/09/21 职场文书
小学语文复习计划
2015/01/19 职场文书