从Python整数变量内存大小占用28字节谈起

  • 实验结果

本机环境64位Python 3.12

  • 内存布局图

0          4          8         12         16         20         24         28

 |----------|----------|----------|----------|----------|----------|----------|

 | ob_refcnt | ob_type    | ob_digit            |             pad               |

 |----------|----------|----------|----------|----------|----------|----------|

在这个布局图中,各个部分的含义如下:

  1. 1) ob_refcnt:4 字节,用于存储对象的引用计数。
  2. 2) ob_type:4 字节,指向对象的类型信息。
  3. 3) ob_digit :8字节,存储整数值。
  4. 4) pad: 12字节,用于填充和对齐,保证整个结构体大小为 28 字节。

在这个布局中,整数值被存储在 ob_digit 中,而引用计数和类型信息分别存储在 ob_refcnt  ob_type 中。填充字节用于对齐和填充,保证整个结构体的大小为 28 字节。这种布局使得整数对象在 Python 3.7 版本之后能够更加高效地存储整数值,并且减少了内存占用

  • 数据结构

Python 中,整数类型的结构体在 CPython 中被定义为 _PyLongObject,其中存储了整数对象的相关信息。以下是整数类型结构体 _PyLongObject 的简化版本:

typedef struct {

    PyObject_VAR_HEAD

    // other fields specific to long integers

    digit ob_digit[1];

} PyLongObject;

在这个结构体中,PyObject_VAR_HEAD 包含了对象的引用计数和类型信息,ob_digit 是一个数组,用于存储整数值。实际上,ob_digit 是一个灵活数组,其大小可以根据需要进行调整,以便存储长整型数据。

Python 3.7 版本之后,整数对象的内存布局调整,PyLongObject 结构体中的 ob_digit 数组用于存储整数值,而不再需要额外的字段来存储整数值。这样的设计使得整数对象的内存占用更加高效,同时也提高了整数对象的操作效率。

  • 再往下一层

PyObject_VAR_HEAD 是 Python 中用于定义可变大小对象的结构体宏。在 CPython 中,所有可变大小的对象(如列表、元组、字符串等)都以相同的结构开始,其中包含对象的引用计数和类型信息。

Python 3.7 中,PyObject_VAR_HEAD 的定义如下:

#define PyObject_VAR_HEAD                   \

    PyObject_HEAD                          \

Py_ssize_t ob_size;  /* Number of items in variable part */

其中:

  • PyObject_HEAD 包含了对象的引用计数和类型信息,通常定义为

#define PyObject_HEAD    \

    _PyObject_HEAD_EXTRA \

    Py_ssize_t ob_refcnt; \

struct _typeobject *ob_type;

  • ob_size 表示可变部分中的项目数量,例如,对于列表对象,ob_size 表示列表中元素的个数。

因此,PyObject_VAR_HEAD 宏实际上是将 PyObject_HEAD 中的引用计数和类型信息与 ob_size 合并在一起,用于定义可变大小对象的结构体。这样的设计使得 Python 能够灵活地处理可变大小对象,同时保持了一致的对象表示方式。

PyObject  Python 中所有对象的基本结构体,定义了所有 Python 对象共享的通用属性。在 CPython 中,PyObject 结构体的定义如下:

typedef struct _object {

    _PyObject_HEAD_EXTRA

    Py_ssize_t ob_refcnt;

    struct _typeobject *ob_type;

} PyObject;

其中:

  • _PyObject_HEAD_EXTRA 包含了一些额外的信息,通常用于调试和特定配置的目的。
  • ob_refcnt 表示对象的引用计数,用于跟踪对象的引用情况,当引用计数为 0 时,对象会被销毁。
  • ob_type 指向对象的类型对象,用于标识对象的类型信息,如整数、字符串、列表等。

PyObject 结构体是所有 Python 对象的基础,所有的 Python 对象都是以 PyObject 结构体为基础进行扩展的。通过这种方式,Python 实现了对象的通用性和灵活性,使得不同类型的对象可以共享相同的基本属性和行为。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/605188.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【大数据】分布式数据库HBase下载安装教程

目录 1.下载安装 2.配置 2.1.启动hadoop 2.2.单机模式 2.3.伪分布式集群 1.下载安装 HBase和Hadoop之间有版本对应关系,之前用的hadoop是3.1.3,选择的HBase的版本是2.2.X。 下载地址: Index of /dist/hbase 配置环境变量&#xff1a…

红米1s 刷入魔趣 (Mokee)ROM(Android 7.1)

目录 背景准备工具硬件(自己准备)软件(我会在文末提供链接) 刷机步骤1. 重启电脑2. 安装驱动3. 刷入TWRP4. 清空数据5. 刷入魔趣6. 开机 结尾下载链接 本文由Jzwalliser原创,发布在CSDN平台上,遵循CC 4.0 B…

LeetCode 138. 随机链表的复制

目录 1.原题链接: 2.结点拆分: 代码实现: 3.提交结果: 4.读书分享: 1.原题链接: 138. 随机链表的复制 2.结点拆分: ①.拷贝各个结点,连接在原结点后面; ②.处…

Lora基础炼丹学习笔记

1、收集数据集 20-30张人物各个角度、各个姿势的图片 2、图片预处理 裁剪 打标签 裁剪必须也要512 * 512 ,因为sd1.5就是用这个尺寸训练的,可以使用后期处理 打标可以勾选这个,Deepbooru对二次元画风更友好 打标也可以使用wb14-tagger的…

Centos7 安装 MySQL5.7 使用 RPM 方式

1 访问网站 https://downloads.mysql.com/archives/community/ 选择合适的版本,点击 Download。 2 上传下载好的 mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar 文件到 Centos7 机器,这里放到了 下载 目录。 3 解压 mysql-5.7.44-1.el7.x86_64.rpm-bundle.…

力扣每日一题119:杨辉三角||

题目 简单 给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: rowIndex 3 输出: [1,3,3,1]示例 2: 输入: rowIndex 0 输出: [1]示例 3: 输入: rowIndex 1 输出…

如何用多个高斯泼溅合成新的场景【3DGS】

3D高斯泼溅(3D Gaussian Splatting)作为一种突破性摄影测量和可视化技术作为 SIGGRAPH 2023 上发表的研究论文的一部分发布。我相信3DGS是允许像你我这样的日常用户扫描 3D 的最佳现代方法并保留有机材料的精细细节,尤其是植物、树木、花卉和…

【青龙面板教程】保姆级拉库 Faker库 以及依赖安装教程

青龙面板最新版拉库教程 新版青龙(订阅)拉库教程 拉库前请打开青龙面板-配置文件 第18行 GithubProxyUrl"" 双引号中的内容清空复制以下拉库命令即可。Faker2 助力池版【安全本地sign防CK泄漏】使用助力池请在群里发"助力池" 机器…

初阶数据结构之单链表详解

目录 一:单链表概念 二:单链表的基本操作 1.定义结点 2.创建链表(初始化链表) 3:新增结点 4.单链表尾插 5.单链表头插 6.单链表尾删 7:单链表头删 8.打印单链表 9.查找单链表结点 10.单链表删除指定结点 1…

【C语言】static关键字用法

目录 一、static修饰局部变量 二、static修饰全局变量 三、static修饰函数 一、static修饰局部变量 首先我们来看两段代码: 代码1&#xff08;不加static&#xff09; #include <stdio.h> void test() {int i 0;i;printf("%d ", i); } int main() {int i…

UE5材质基础(2)——数学节点篇

UE5材质基础&#xff08;2&#xff09;——数学节点篇1 目录 UE5材质基础&#xff08;2&#xff09;——数学节点篇1 Add节点 Append节点 Abs节点 Subtract节点 Multiply节点 Divide节点 Clamp节点 Time节点 Lerp节点 Add节点 快捷键&#xff1a;A鼠标左键 值相加…

C++学习第十二天(继承)

1、继承的概念以及定义 继承的概念 继承机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行拓展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象程序设计的层次结构&#x…

EditReady for Mac激活版:专业视频转码工具

对于视频专业人员来说&#xff0c;一款高效的视频转码工具是不可或缺的。EditReady for Mac正是这样一款强大的工具&#xff0c;它拥有简洁直观的操作界面和强大的功能&#xff0c;让您的视频处理工作事半功倍。 EditReady for Mac支持多种视频格式的转码&#xff0c;并且支持常…

多线程学习Day09

10.Tomcat线程池 LimitLatch 用来限流&#xff0c;可以控制最大连接个数&#xff0c;类似 J.U.C 中的 Semaphore 后面再讲 Acceptor 只负责【接收新的 socket 连接】 Poller 只负责监听 socket channel 是否有【可读的 I/O 事件】 一旦可读&#xff0c;封装一个任务对象&#x…

阿里云VOD视频点播流程(2)

二、视频点播 1、入门代码 基于OSS原生SDK上传 &#xff0c;参考文档&#xff1a;https://help.aliyun.com/zh/vod/user-guide/upload-media-files-by-using-oss-sdks?spma2c4g.11186623.0.0.1f02273fj4lxNJ 视频点播面向开发者提供了丰富的上传方式&#xff0c;其中上传SDK&…

软件测试实战项目(含电商、银行、APP等)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 今天给大家带来几个软件测试项目的实战总结及经验&#xff0c;适…

ps5电玩计时收费系统软件教程,电玩店适合的计时器,电脑定时语音提醒

ps5电玩计时收费系统软件教程&#xff0c;电玩店适合的计时器&#xff0c;电脑定时语音提醒 一、前言 以下软件操作教程以&#xff0c;佳易王电玩计时计费管理软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、计时计费功能&#xff1a;只…

PHPStudy 访问网页 403 Forbidden禁止访问

涉及靶场 upload-labd sqli-labs pikachu dvwa 以及所有部署在phpstudy中的靶场 注意&#xff1a;一定要安装解压软件 很多同学解压靶场代码以后访问报错的原因是&#xff1a;电脑上没有解压软件。 这个时候压缩包看起来就是黄色公文包的样子&#xff0c;右键只有“全部提取…

SpringCloud Alibaba Sentinel 修改Dashboard用户名和密码

目录 一、下载Sentinel的Jar包 二、在启动时修改用户名和密码的命令 三、测试登录成功 在网上找到了一大堆文章&#xff0c;没一个有用的&#xff0c;最终还是通过不断测试找到了这个方法。 一、下载Sentinel的Jar包 Releases alibaba/Sentinel GitHub 二、在启动时修改…

设计模式:命令模式

文章目录 一、什么是命令模式二、命令模式结构三、命令模式实现步骤四、命令模式应用场景 一、什么是命令模式 它允许将请求封装为对象&#xff0c;一个请求对应于一个命令&#xff0c;将发出命令的责任和执行命令的责任分割开。每一个命令都是一个操作&#xff1a;请求的一方…
最新文章