python一个对象占用多少资源(python一个对象占用多少资源空间)

作者&投稿:惠强 (若有异议请与网页底部的电邮联系)
~

导读:本篇文章首席CTO笔记来给大家介绍有关python一个对象占用多少资源的相关内容,希望对大家有所帮助,一起来看看吧。

python内存管理机制

由于python中万物皆对象,所以python的存储问题是对象的存储问题。实际上,对于每个对象,python会分配一块内存空间去存储它。

那么python是如何进行内存分配,如何进行内存管理,又是如何释放内存的呢?

总结起来有一下几个方面:引用计数,垃圾回收,内存池机制

python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数

1、对象被创建a='abc'

2、对象被引用b=a

3、对象被其他的对象引用li=[1,2,a]

4、对象被作为参数传递给函数:foo(x)

1、变量被删除dela或者delb

2、变量引用了其他对象b=c或者a=c

3、变量离开了所在的作用域(函数调用结束)比如上面的foo(x)函数结束时,x指向的对象引用减1。

4、在其他的引用对象中被删除(移除)li.remove(a)

5、窗口对象本身被销毁:delli,或者窗口对象本身离开了作用域。

即对象p中的属性引用d,而对象d中属性同时来引用p,从而造成仅仅删除p和d对象,也无法释放其内存空间,因为他们依然在被引用。深入解释就是,循环引用后,p和d被引用个数为2,删除p和d对象后,两者被引用个数变为1,并不是0,而python只有在检查到一个对象的被引用个数为0时,才会自动释放其内存,所以这里无法释放p和d的内存空间

垃圾回收机制:①引用计数,②标记清除,③分带回收

引用计数也是一种垃圾收集机制,而且也是一种最直观,最简单的垃圾收集技术.当python某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了.(如果出现循环引用的话,引用计数机制就不再起作用了)

优点:简单实时性,缺点:维护引用计数消耗资源,且无法解决循环引用。

如果两个对象的引用计数都为1,但是仅仅存在他们之间的循环引用,那么这两个对象都是需要被回收的,也就是说它们的引用计数虽然表现为非0,但实际上有效的引用计数为0,.所以先将循环引用摘掉,就会得出这两个对象的有效计数.

标记清除算法也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。

为了提高效率,有很多对象,清理了很多次他依然存在,可以认为,这样的对象不需要经常回收,可以把它分到不同的集合,每个集合回收的时间间隔不同。简单的说这就是python的分代回收。

具体来说,python中的垃圾分为1,2,3代,在1代里的对象每次回收都会去清理,当清理后有引用的对象依然存在,此时他会进入2代集合,同理2代集合清理的时候存在的对象会进入3代集合。

每个集合的清理时间如何分配:会先清理1代垃圾,当清理10次一代垃圾后会清理一次2代垃圾,当清理10次2代垃圾后会清理3代垃圾。

在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,当创建大量消耗小内存的对象时,频繁调用new/malloc会导致大量的内存碎片,致使效率降低。

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

Python中有分为大内存和小内存:(256K为界限分大小内存)

大小小于256kb时,pymalloc会在内存池中申请内存空间,当大于256kb,则会直接执行new/malloc的行为来申请新的内存空间

在python中-5到256之间的数据,系统会默认给每个数字分配一个内存区域,其后有赋值时都会指向固定的已分配的内存区域

在运行py程序的时候,解释器会专门分配一块空白的内存,用来存放纯单词字符组成的字符串(数字,字母,下划线)

字符串赋值时,会先去查找要赋值的字符串是否已存在于内存区域,已存在,则指向已存在的内存,不存在,则会在大整数池中分配一块内存存放此字符串

请教各位牛人,python中有没有计算某个对象占用内存大小的函数

1

2

s='abc'

printsys.getsizeof(s)

如果你要监测所有的变量,可以用python的smiley模块监测所有的内存变量情况

求助protobuf在python中创建一个对象为何要占用那么多内存

例如我定义一个message

messageTestMes{

stringtest=1;

}

我只定义了一个string。然后我在python程序中用它,作为对比,也用了python自己的string

@profile

defaddstring():

sss=[]

foriinrange(1000):

info="dsdf_sdf"+str(i)

sss.append(info)

@profile

defaddtestmes():

sss=[]

foriinrange(1000):

test_mes=TestMes()

sss.append(test_mes)

执行命令

python-mmemory_profilertest.py

打印结果是

Filename:testing.py

Line#MemusageIncrementLineContents

================================================

34519.211MiB0.000MiB@profile

346defaddstring():

34719.211MiB0.000MiBsss=[]

34819.219MiB0.008MiBforiinrange(1000):

34919.219MiB0.000MiBinfo="$sdf"+str(i)

35019.219MiB0.000MiBsss.append(info)

35119.219MiB0.000MiBprintlen(sss)

35219.219MiB0.000MiBprintsss[999]

Filename:testing.py

Line#MemusageIncrementLineContents

================================================

35419.219MiB0.000MiB@profile

355defaddtestmes():

35619.219MiB0.000MiBsss=[]

35719.977MiB0.758MiBforiinrange(1000):

35819.977MiB0.000MiBtest_mes=TestMes()

35919.977MiB0.000MiBsss.append(test_mes)

我用pythonstring的只用了0.008M内存,而用protobufmessage的,用了0.758M内存。需要保持很多信息

使用sys.getsizeof查看python对象的内存占用

使用sys.getsizeof方法可以查看python对象的内存占用,单位:字节(byte)

实际上是调用了__sizeof__方法:

有些数据类型在Python3和Python2中占用的内存是不同的,例如range:

关于这个值是怎么算出来的,有待研究~

暂时已知:这个值包括该对象的数值、签名(包括数据类型、参数、调用方式等)等一系列数据所占总内存。可变对象所占内存可能极小,因为对象是指针,指向很大的数据。

Python对象

众所周知,Python是一门面向对象的语言,在Python无论是数值、字符串、函数亦或是类型、类,都是对象。

对象是在堆上分配的结构,我们定义的所有变量、函数等,都存储于堆内存,而变量名、函数名则是一个存储于栈中、指向堆中具体结构的引用。

要想深入学习Python,首先需要知道Python对象的定义。

我们通常说的Python都是指CPython,底层由C语言实现,源码地址:cpython[GitHub]

Python对象的定义位于Include/object.h,是一个名为PyObject的结构体:

Python中的所有对象都继承自PyObejct,PyObject包含一个用于垃圾回收的双向链表,一个引用计数变量ob_refcnt和一个类型对象指针ob_type

从PyObejct的注释中,我们可以看到这样一句:每个指向可变大小Python对象的指针也可以转换为PyVarObject*(可变大小的Python对象会在下文中解释)。PyVarObejct就是在PyObject的基础上多了一个ob_size字段,用于存储元素个数:

在PyObject结构中,还有一个类型对象指针ob_type,用于表示Python对象是什么类型,定义Python对象类型的是一个PyTypeObject接口体

实际定义是位于Include/cpython/object.h的_typeobject:

在这个类型对象中,不仅包含了对象的类型,还包含了如分配内存大小、对象标准操作等信息,主要分为:

以Python中的int类型为例,int类型对象的定义如下:

从PyObject的定义中我们知道,每个对象的ob_type都要指向一个具体的类型对象,比如一个数值型对象100,它的ob_type会指向int类型对象PyLong_Type。

PyTypeObject结构体第一行是一个PyObject_VAR_HEAD宏,查看宏定义可知PyTypeObject是一个变长对象

也就是说,归根结底类型对象也是一个对象,也有ob_type属性,那PyLong_Type的ob_type是什么呢?

回到PyLong_Type的定义,第一行PyVarObject_HEAD_INIT(PyType_Type,0),查看对应的宏定义

由以上关系可以知道,PyVarObject_HEAD_INIT(PyType_Type,0)={{_PyObject_EXTRA_INIT1,PyType_Type}0},将其代入PyObject_VAR_HEAD,得到一个变长对象:

这样看就很明确了,PyLong_Type的类型就是PyType_Typ,同理可知,Python类型对象的类型就是PyType_Type,而PyType_Type对象的类型是它本身

从上述内容中,我们知道了对象和对象类型的定义,那么根据定义,对象可以有以下两种分类

Python对象定义有PyObject和PyVarObject,因此,根据对象大小是否可变的区别,Python对象可以划分为可变对象(变长对象)和不可变对象(定长对象)

原本的对象a大小并没有改变,只是s引用的对象改变了。这里的对象a、对象b就是定长对象

可以看到,变量l仍然指向对象a,只是对象a的内容发生了改变,数据量变大了。这里的对象a就是变长对象

由于存在以上特性,所以使用这两种对象还会带来一种区别:

声明s2=s,修改s的值:s='newstring',s2的值不会一起改变,因为只是s指向了一个新的对象,s2指向的旧对象的值并没有发生改变

声明l2=l,修改l的值:l.append(6),此时l2的值会一起改变,因为l和l2指向的是同一个对象,而该对象的内容被l修改了

此外,对于字符串对象,Python还有一套内存复用机制,如果两个字符串变量值相同,那它们将共用同一个对象:

对于数值型对象,Python会默认创建0~28以内的整数对象,也就是0~256之间的数值对象是共用的:

按照Python数据类型,对象可分为以下几类:

Python创建对象有两种方式,泛型API和和类型相关的API

这类API通常以PyObject_xxx的形式命名,可以应用在任意Python对象上,如:

使用PyObjecg_New创建一个数值型对象:

这类API通常只能作用于一种类型的对象上,如:

使用PyLong_FromLong创建一个数值型对象:

在我们使用Python声明变量的时候,并不需要为变量指派类型,在给变量赋值的时候,可以赋值任意类型数据,如:

从Python对象的定义我们已经可以知晓造成这个特点的原因了,Python创建对象时,会分配内存进行初始化,然后Python内部通过PyObject*变量来维护这个对象,所以在Python内部各函数直接传递的都是一种泛型指针PyObject*,这个指针所指向的对象类型是不固定的,只能通过所指对象的ob_type属性动态进行判断,而Python正是通过ob_type实现了多态机制

Python在管理维护对象时,通过引用计数来判断内存中的对象是否需要被销毁,Python中所有事物都是对象,所有对象都有引用计数ob_refcnt。

当一个对象的引用计数减少到0之后,Python将会释放该对象所占用的内存和系统资源。

但这并不意味着最终一定会释放内存空间,因为频繁申请释放内存会大大降低Python的执行效率,因此Python中采用了内存对象池的技术,是的对象释放的空间会还给内存池,而不是直接释放,后续需要申请空间时,优先从内存对象池中获取。

pythontimer占用内存

python程序在运行过程之中会单独开辟出一个进程来执行,而很多小伙伴都发现程序在运行过程之中所占用的内存会越来越大,但是不知道是什么原因以及如何解决。那么下文会来讲解一下python程序内存占用过大的原因和解决方法,感兴趣的和有需要的话就往下看看吧。

?

一、原因

首先需要知道的一点就是,python是面向对象编程的语言,那么就表示在其程序之中一切皆为对象。而每一个对象在创建是都会在内存中开辟空间来占用位置,这样就会造成一开始的内存占用。

虽然说python中有自己的内存管理机制和垃圾处理方式,但是它对于一些占用内存过多的对象不会马上释放,只有当这个对象不处于引用状态时才会处理它。

二、解决方法

既然知道了python程序内存都是因为有对象才将其占用的,那么正确的解决方法就是将对象在调用完毕之后马上删除掉。该方法需要用到关键字del和gc模块,使用del关键字删除变量之后,调用gc模块来马上启动python垃圾处理机制就可以直接将其彻底从内存空间清除,代码示例如下所示:

结语:以上就是首席CTO笔记为大家整理的关于python一个对象占用多少资源的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于python一个对象占用多少资源的相关内容别忘了在本站进行查找喔。




python中已经有一个对象student+现需要给其添加age属性,语句是什么...
可以使用点(.)运算符来添加属性。在 Python 中,你可以像下面这样为一个对象添加属性:Copy code student.age = 20 这个语句为 student 对象添加了一个名为 age 的属性,并将其值设置为 20。你可以将其替换为不同的属性名称和值,根据需要随时添加不同的属性。

在Python中什么用于判断一个对象是否属于另一个对象
查看关系。1、在Python查看两者之间是否属于上下级关系或是否属于函数关系。2、在查看两者之间是否属于加减或从被除关系。3、查看一个对象和另一个对象之间存在什么样的联系关联。

python为什么x=1可以自动定义一个int对象
python中x=1可以自动定义一个int对象的原因为Python是一种面向对象的编程语言,设计理念是一切皆为对象。在Python中,整数、字符串、列表等都是对象,具有属性和方法。因此,当你定义一个变量时,实际上是在创建一个对象,并将该对象的引用赋给变量。在这种情况下,整数1被封装在一个名为int的整数对象...

Python中的类为什么要实例化为一个对象才能使用
类就好比是一类事物的抽象,是一个模板,拥有这一类事物的属性和功能。但是对于“人类”这个类来说,每个人的属性和要做的事又是不一样的,所以需要实例化,实例对象就是“人类”这个类的具体对象,后续就通过“小明”这个实例对象进行操作。😂

在Python中面向对象该如何编程
一.如何定义一个类在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法。1.什么是面向对象面向对象(oop)是一种抽象的方法来理解这个世界,世间万物都可以抽象成一个对象,一切事物都是由对象构成的。应用在编程中,是一种开发程序的方法,它将对象作为程序的基本...

怎么理解python中的“一切皆对象”?
"一切皆对象" 是Python语言中一个非常重要的概念。它的意思是在Python中,每一个变量、函数、类、模块等都是一个对象。这些对象都有自己的属性和方法,可以像操作其他对象一样操作它们。Python中的每个对象都有一个类型(type),例如,一个整数类型的对象的类型是int,一个字符串类型的对象的类型是str...

Python的类和对象入门
属性引用的语法就是一般的标准语法:obj.name。比如XiaoMing.height和XiaoMing.run就是属性引用,前者会返回一条数据,而后者会返回一个方法对象。这里也支持对类属性进行赋值操作,比如为类中的weight属性赋予一个新值。而类的实例化可以将类对象看作成一个无参函数的赋值给一个局部变量,如下:ming就是...

python中如何判断一个对象是否一个类的实例
可以用 isinstance(s, myclass)来判断 如果是s是mycalss的实例,返回True,否则返回False

python入门-14-类与对象
在编程中,类和对象是核心概念。类就像设计图纸,定义了对象的数据结构(属性)和行为(方法),而对象则是类的具体实例,如“Dog”类的一个实例就是一只特定的狗“Rex”。在Python中,使用关键字`class`创建类,如`Dog`类,其`__init__`方法用于初始化对象,`self`代表对象本身,而`name`等属性...

python定义一个学生类,包含三个属性
def __init__(self, name, age, score):self.name = name self.age = age self.score = score isinstance函数判断一个对象是否是一个已知的类型,类似type def get_name(self):if isinstance(self.name, str):return self.name def get_age(self):if isinstance(self.age, int):return self...

良庆区15824637767: python2.7中一个float 占多少字节 -
於垂复方: 如同,是24

良庆区15824637767: Python如何查看变量占用空间大小
於垂复方: python中用len(),如果导入工具包也可以调用sizeof函数

良庆区15824637767: 请教各位牛人,python中有没有计算某个对象占用内存大小的函数 -
於垂复方: 1 2s = 'abc' print sys.getsizeof(s)如果你要监测所有的变量,可以用python的smiley 模块监测所有的内存变量情况

良庆区15824637767: PYTHON 的变量作用域与内存分配 -
於垂复方: 原理:python中任何变量都是对象,所以参数只支持引用传递方式.即通过名字绑定的机制,把实际参数的值和形式参数的名称绑定在一起,形式参数和实际参数指向内存中的同一个存储空间. 回答问题2: 每一次给变量赋值就是把这个名称的...

良庆区15824637767: python 中的out of memory是怎么回事,内存不够吗? -
於垂复方: Python中大量采用了内存对象池的技术,使用这种技术可以避免频繁地申请和释放内存空间.因此在析构时,通常都是将对象占用的空间归还到内存池中.举个例子,如果你无意识的写了一个循环之类的,申请了10*1024*1024个16字节的小内存.即使你每次都消除了引用,Python虚拟机也不会将内存释放给系统,这种情况下会出现内存不足.也是Python中的一种内存泄露.不知道是不是跟你的情况一样?如果是上述情况的话,加内存条是治标不治本的,因为长期运营的项目,只要有内存泄露,结果到了一定的积累,都是一个结果——内存不足.

良庆区15824637767: python的优缺点是什么? -
於垂复方: Python这门语言的魅力和影响力已经远超Java、C、C++等编程语言前辈,2018年主流的十大编程语言中,Python排名第一.被广大使用者誉为“更美好”编程语言.也常常被昵称为“胶水语言”,Python这门语言拥有很多的优势,看完之后你会...

良庆区15824637767: PYTHON 下列数据类型中哪个是可变数据类型? -
於垂复方: python很热门,很好学的. 可变数据类型:列表list和字典dict、集合set; 不可变数据类型:字符串型string和元组tuple. 学会做总结: Python 6个标准数据类型.png 所以,这题选ABC.

良庆区15824637767: Python的特点有哪些特点 -
於垂复方: Python是一种计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发. Python的特点如下: 1、简单 Python是一...

良庆区15824637767: python对象是什么概念? -
於垂复方: 所说所有的变量都是对象. 对象在python里,其实是一个指针,指向一个数据结构,数据结构里有属性,有方法.对象通常就是指变量.从面向对象OO的概念来讲,对象是类的一个实例.在python里很简单,对象就是变量.class A:myname="class a" 上面就是一个类.不是对象 a=A() 这里变量a就是一个对象. 它有一个属性(类属性),myname,你可以显示出来 print a.myname所以,你看到一个变量后面跟点一个小数点.那么小数点后面就是它的属性或者是方法.带括号的方法.不带就是属性.

良庆区15824637767: python怎么打开文件模式 -
於垂复方: 读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网