python 对象内存分析

本文详细分析了Python中不同类型的对象占用内存的情况,包括内建对象如整型、浮点型等,以及自定义对象的内存占用特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python对象内存分析

一、python内建对象

python内建对象占用内存的情况又分为定长对象与非定长对象(变长)

1.1 定长对象,对象在内存中所占大小不会变化的对象

包括int,float,long,bool,complex和dict

测试程序如下:

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sys
print "value\t\ttype\t\tmemsize"
#int test
alist=[0,1,10,-1,-444,12313]
for i in alist:
        print "%d\t\t%s\t\t%s"%(i,type(i),sys.getsizeof(i))
#float test
blist=[0.0,1.0,111.1,2323.22,-1.1]
for i in blist:
        print "%f\t\t%s\t\t%s"%(i,type(i),sys.getsizeof(i))
#long test
clist=[0l,1l,2l,-1111l,45445l]
for i in clist:
        print "%d\t\t%s\t\t%s"%(i,type(i),sys.getsizeof(i))
#bool test
dlist=[True,False]
for i in dlist:
        print "%s\t\t%s\t\t%s"%(i,type(i),sys.getsizeof(i))
#complex test
elist=[0j,1+0j,1+1j,1000-23j,-100+5j]
for i in elist:
        print i,"\t\t%s\t\t%s"%(type(i),sys.getsizeof(i))
#dict test

flist=[{},{'a':'b'},{'a':'b','c':1},{'a':'b','c':1,'d':'你好'}]
for i in flist:
        print i,"\t\t%s\t\t%s"%(type(i),sys.getsizeof(i))

 运行结果如下:

value		type		memsize
0		<type 'int'>		24
1		<type 'int'>		24
10		<type 'int'>		24
-1		<type 'int'>		24
-444		<type 'int'>		24
12313		<type 'int'>		24
0.000000		<type 'float'>		24
1.000000		<type 'float'>		24
111.100000		<type 'float'>		24
2323.220000		<type 'float'>		24
-1.100000		<type 'float'>		24
0		<type 'long'>		24
1		<type 'long'>		28
2		<type 'long'>		28
-1111		<type 'long'>		28
45445		<type 'long'>		28
True		<type 'bool'>		24
False		<type 'bool'>		24
0j 		<type 'complex'>		32
(1+0j) 		<type 'complex'>		32
(1+1j) 		<type 'complex'>		32
(1000-23j) 		<type 'complex'>		32
(-100+5j) 		<type 'complex'>		32
{} 		<type 'dict'>		280
{'a': 'b'} 		<type 'dict'>		280
{'a': 'b', 'c': 1} 		<type 'dict'>		280
{'a': 'b', 'c': 1, 'd': '\xe4\xbd\xa0\xe5\xa5\xbd'} 		<type 'dict'>		280

 有运行结果可以看出各个定长对象所占的内存:

int和float:24

long:这个有点特殊,对于0l,python识别为long type,但是所占内存是24,除了0l所占内存为24以外,其他的都为28

complex(复数):32

dict(字典):280

1.2 变成对象,会随着对象变化所占用的内存会变化

包括:list,tuple,str

测试代码:

#/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
#str test
print "str-length\ttype\tmemsize"
ua='你好'
ga=ua.decode('utf-8').encode('gbk')
ba=ua.decode('utf-8').encode('big5')
ga1=ua.decode('utf-8').encode('gb2312')

alist=['','a','ab',ua,ga,ba,ga1]
for s in alist:
        print "%d\t%s\t%s"%(len(s),type(s),sys.getsizeof(s))

print "list-length\ttype\tmemsize"
#list test
alist=[[],['a','b'],['abc','你好'],[11,12,'eee']]
for li in alist:
        print "%d\t%s\t%s"%(len(li),type(li),sys.getsizeof(li))

print "%d\t%s\t%s"%(len(alist),type(alist),sys.getsizeof(alist))

#tuple test
print "tuple-len\ttype\tmemsize"
alist=((),('a',),('abc','你好'),(11,12,'eeee'))
for tp in alist:
        print "%d\t%s\t%s"%(len(tp),type(tp),sys.getsizeof(tp))

print "%d\t%s\t%s"%(len(alist),type(alist),sys.getsizeof(alist))

 结果:

str-length	type	memsize
0	<type 'str'>	37
1	<type 'str'>	38
2	<type 'str'>	39
6	<type 'str'>	43
4	<type 'str'>	41
4	<type 'str'>	41
4	<type 'str'>	41
list-length	type	memsize
0	<type 'list'>	72
2	<type 'list'>	88
2	<type 'list'>	88
3	<type 'list'>	96
4	<type 'list'>	104
tuple-len	type	memsize
0	<type 'tuple'>	56
1	<type 'tuple'>	64
2	<type 'tuple'>	72
3	<type 'tuple'>	80
4	<type 'tuple'>	88

分析结果可知:

str:空str所占内存为37,若str长度每加1,则内存所占大小相应加1

list:空列表所占内存为72,长度每增加1,则所占内存加8

tuple:空元组所占内存为56,长度每加1,所占了内存加8

空字符串为什么是37,而不是36或38,因为这里介绍所有的对像内存都为偶数,python内部维护字符串的机制和C中维护字符串的机制是一样的,即在末尾加'\0',这个占了1个字节,所以内存大小表现为36+1=37

补充:

python中还有一个比较特殊的对象,就是类型对像

>>> tlist=(int,float,long,str,complex,dict,list,tuple,bool,type)
>>> for i in tlist:
...     print sys.getsizeof(i)
... 
872
872
872
872
872
872
872
872
872
872

类型对象也是定长的为872

基类对象object所占内存也为872

二、自建对象

测试程序:

 

#!/usr/bin/env python
import sys
class A:
        def __init__(self):
                self.value=2
        def test(self):
                print self.value
class B(object):
        def test(self):
                print "test"

class C(float):
        def __init__(self):
                self.value=1
        def test(self):
                print self.value
class D(object):
        pass
class E(A):
        pass
print "A  :%s\t%s"%(type(A),sys.getsizeof(A))
print "A():%s\t%s"%(type(A()),sys.getsizeof(A()))
print "B  :%s\t%s"%(type(B),sys.getsizeof(B))
print "B():%s\t%s"%(type(B()),sys.getsizeof(B()))
print "C  :%s\t%s"%(type(C),sys.getsizeof(C))
print "C():%s\t%s"%(type(C()),sys.getsizeof(C()))
print "D  :%s\t%s"%(type(D),sys.getsizeof(D))
print "D():%s\t%s"%(type(D()),sys.getsizeof(D()))
print "E  :%s\t%s"%(type(E),sys.getsizeof(E))
print "E():%s\t%s"%(type(E()),sys.getsizeof(E()))

结果:

A  :<type 'classobj'>	104
A():<type 'instance'>	72
B  :<type 'type'>	904
B():<class '__main__.B'>	64
C  :<type 'type'>	904
C():<class '__main__.C'>	72
D  :<type 'type'>	904
D():<class '__main__.D'>	64
E  :<type 'classobj'>	104
E():<type 'instance'>	72

 有结果可以看出:

A和E对象没有继承类型对象,未申明基类的情况下,类型python解释为’classobj',所占内存为104,实例化后类型为instance 内存为72

BD对象都是继承自基类object,类型为type,所占内存为904,实例化后类型为class,所占内存为64

C对象继承自类型对象 float,类型为type,所占内存为904,实例化后类型为class,所占内存为72

 

PS:object是所有对象的基类,python中所有对象都继承自object

### Python 对象内存管理深度解析 Python对象内存管理机制是一个复杂但高效的体系,主要包括以下几个核心部分: #### 1. 引用计数 Python 使用引用计数作为其主要的内存管理策略之一。每个对象都维护了一个 `ob_refcnt` 属性,用于记录该对象当前被引用的次数[^5]。当一个新变量指向这个对象时,引用计数加一;反之,如果某个变量不再指向它,则引用计数减一。一旦引用计数降为零,说明没有任何地方再使用此对象,此时 Python 将自动释放该对象占用内存。 #### 2. 垃圾回收机制 除了引用计数外,Python 还提供了一套完整的垃圾回收系统以处理更复杂的场景,例如循环引用等问题。具体来说,Python 的垃圾回收分为三类: - **引用计数**:实时追踪对象的生命周期。 - **标记清除**:针对无法通过简单引用计数解决的情况(如循环引用),定期扫描未被访问的对象并清理它们。 - **分代回收**:基于对象存活时间的不同将其划分为多个世代,优先回收较年轻的对象,从而提高性能效率[^3]。 可以通过导入标准库中的 `gc` 模块来自定义这些行为设置参数或强制执行某些操作。 #### 3. 内存池机制 对于小型对象 (<256KB),Python 利用了专门设计的小型缓冲区分配器 Pymalloc 来进一步优化资源利用状况。这种方式能够显著降低因频繁申请/释放小块空间而导致的整体开销,并减少由于长期运行可能引发的碎片化现象发生几率[^4]。 以下是展示如何查看某特定实例内部状态以及手动触发GC过程的一个例子: ```python import sys import gc class MyClass: pass obj = MyClass() print(f"Reference count before creating a new reference: {sys.getrefcount(obj)}") another_reference = obj print(f"Reference count after creating another reference: {sys.getrefcount(obj)}") del another_reference print(f"Reference count after deleting one of the references: {sys.getrefcount(obj)}") # Manually run garbage collection collected_objects = gc.collect() print(f"{collected_objects} objects were collected during manual GC.") ``` 上述脚本展示了基本原理的同时也体现了灵活性所在之处在于允许程序员介入控制流程当中去调整适应不同需求环境下的表现形式. --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值