Python源码剖析1-整数对象PyIntObject

news2024/9/21 14:37:32

1、PyIntObject 对象

[intobject.h]
typedef struct {
	PyObject_HEAD
    long ob_ival;
} PyIntObject

PyIntObject是一个不可变(immutable)对象。Python内部也大量的使用整数对象,我们在自己的代码中也会有大量的创建销毁整型对象的操作,因此单独的维护整形对象并对其申请内存和释放内存是不现实的。Python给出的解决方案是将整形对象通过一定的结构连接在一起的整数对象系统:整数对象池,一个整形对象的缓冲池机制。

对象创建:

  • PyInt_FromString
  • PyInt_FromLong
  • PyInt_FromUnicode

其中,后两种方法实际上是先转换成浮点数,然后再调用PyInt_FromFloat,这实际上是 Adaptor Pattern 的思想:对核心函数进行接口转换。

2、小整数对象

小整数会频繁的使用。在 Python 中,所有的对象都是存活在系统堆上。这样的操作不仅大大降低了运行效率,而且会在系统堆上造成内存碎片。

所以解决方法就是对小整数使用对象池技术,正是因为使用缓冲池,PyIntObject才是不可变对象。对象池中的每一个对象可以被安全的共享。那么,多小才算小整数?默认的范围是-5到256,这个值不可以动态修改,要想修改只能修改源代码然后重新编译。

3、大整数对象

对于大整数对象,是一次申请一块内存,这块内存用PyIntBlock结构体管理,该结构体中中有一个PyIntObject数组(会链表形式维护)来供大整数对象使用,还有一个用于形成链表的指向下一个block的指针。如果这一整块内存都祸祸光了(默认一个block可以存放82个int对象),就再申请一个PyIntBlock,然后用一个单向链表维护所有的PyIntBlock,这个链表就是大整数对象缓冲池两个重要变量其中之一:block_list指针。

这个 block 链表维护的是一整块block,是block级别的,我要使用的是PyIntObject,每次使用的话总不能进到block去遍历数组去找到一个还没使用的PyIntObject吧,所以下一个大整数缓冲池至关重要的变量就是free_list指针,这个指向一个链表,链表中的所有元素是PyIntObject。

4、引用计数:ob_refcnt

Python通过管理对象的引用计数来决定对象在内存中的存在与否,Python一切皆对象,所有对象都有一个 ob_refcnt 变量。这个变量维护这对象的引用计数,也决定这对象的存在与消亡。

对于某一对象A,当有一个新的PyObject * 引用该对象时,A的引用计数应该增加,而当PyObject * 被删除时, 引用计数应该减少。计数为0时,A 可以从堆上被删除,释放内存。

5、运行时整数对象及其类型之间的关系

对于int(10) 的 ob_refcnt 来说可以理解为多个ref 引用了这个对象,ob_type 是指向其类型对象的指针,ob_ival 是具体数值。

int(10) 是PyIntObject 的实例对象,比PyObject 多一个ob_ival 成员,PyInt_Type、PyBaseObject_Type、PyType_Type 都是PyTypeObject 的实例对象。PyInt_Type 的 tp_base 指向其基类对象 PyBaseObject_Type,而他们的 ob_type 都指向 PyType_Type。

6、不同PyintBlock中空闲内存的互连:tp_dealloc

Python中不同对象在销毁时会进行不同的动作,销毁动作在与对象对应的类对象中被定义,这个关键操作就是类型对象中的tp_dealloc。

static void int_dealloc(PyIntObject *v)
(
    if (PyInt_CheckExact(v))  {
        v->ob_type = (struct _typeobject *)free_list;
        free_list = v;
    }
    else
        v->obtype->tp_free((Pyobject *)v);

tp_dealloc的作用:

由block_list维护的PyIntBlock链表中的内存实际是所有的大整数对象共同分享的。当一个PyIntObject对象被销毁时,它所占的内存并不会被释放,归还给系统,Python会继续保留着。将来提供给别的PyIntObject使用,所以Python应该将其链入了free_list所维护的自由内存链表。

以下是创建可删除PyIntObject对象2、3、4的过程中,内存中对象PyIntObject以及free_list指针的变化:

不同PyIntBlock对象中空闲内存的互连是在int_dealloc被调用时实现的。

 注意:在int_dealloc中,永远不会向系统堆交还任何内存,一旦系统堆中的某块内存被python申请用于整数对象,那么这块内存在Python进程结束之前,将永远不会得到释放。

由于内存共享,Python用于实现该对象池的内存与历史上创建的整数对象的个数无关,而仅仅与同一时刻共存的整数对象个数的最大值有关

————————————————

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

霍夫曼树:霍夫曼编码(Huffman Tree:Huffman Coding)

预计阅读时间:10分钟 一、简介 霍夫曼树常处理符号编写工作。根据整组数据中符号出现的频率高低,决定如何给符号编码。如果符号出现的频率越高,则给符号的码越短,相反符号的号码越长。 相关术语 路径:从书中一个节点…

Docker安装可视化管理器Portainer

Docker安装可视化管理器Portainer Portainer 提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm 集群和服务等集中管理和操作、登录用户管理和控制…

Linux/Windows Redis的下载与安装

Redis简介 参考视频教程: https://www.bilibili.com/video/BV13a411q753?p143 Redis下载与安装 Windows版 下载地址: https://github.com/microsoftarchive/redis/releases Linux版下载地址: https://download.redis.io/releases/ 1. Window版本 1.1 redis下载 官网下载…

用ACL实现防火墙功能

目录 实验目的: 实验所需软硬件 实验步骤: 1、按以下拓扑接好线路。 2、配置好设备的IP地址和静态路由,使得所有设备可以互通。(配置截图) PC2 PC0 Router0 Router1​编辑 Server 3、测试各PC/服务器互联状…

基于KubeSphere图形编辑面板构建微服务项目的DevOps 系统

文章目录相关文章部署过程准备工作创建 DevOps 项目创建凭证创建流水线编辑流水线JAVA后端微服务拉取源码构建源码构建镜像推送镜像部署项目VUE前端拉取源码构建源码构建镜像推送镜像部署项目运行流水线查看流水线详情完整流水线脚本微服务后端VUE前端参考相关文章 kubernetes…

Grafana+Prometheus打造运维监控系统(一)-安装篇

1. Prometheus、Grafana介绍 Prometheus是一个开源的系统监控和报警系统,Grafana 是一个开源的监控数据分析和可视化套件,利用GrafanaPrometheus组合,打造运维日常的各种指标监控以及数据可视化。 2. Prometheus 2.1 下载 访问&#xff1…

专利-分析方法总结

目录 一、专利分析的意义 二、专利分析的方法: 2.1、行业专利信息分析 2.1.1、专利技术发展趋势分析 2.1.2、专利区域分布分析 2.1.3、专利相关人分析 2.1.4、专利技术主题分析 2.1.5、技术发展路线分析 2.1.6、专利技术功效分析 2.1.7、专利运营分析 3.…

node环境的搭建

一、node的安装(可以去文末直接安装nvm管理器,就不用配置了) 1 下载 | Node.js,也可以下载以往版本,window是以msi结尾的文件 2 安装,直接一直安装就行,如果有之前安装的版本,先进行卸载,然后再进行安装 3 安装完成后查看版本号 node -vnp…

Linux下文件目录权限管理chmod, chown, chgrp,umask命令使用总结

在Linux系统下常用的文件目录权限管理命令有chmod, chown, chgrp,umask,一直以来都在用,但是没有太注意它们的区别,今天就在这篇文章做个总结。 目录 1. chmod 2. chown 3. chgrp 4. umask 1. chmod 作用:修改某个目录或文件…

C语言实现学生管理系统(顺序表版)

前言 设计知识 使用语言:C语言 数据结构类型:顺序表 内容导图 效果展示 内容目录前言设计知识内容导图效果展示静态管理系统菜单的实现选择功能实现静态开辟空间实现增删功能增加功能实现删除功能实现实现查找功能实现修改功能实现排序功能动态管理系…

rollup打包工具快速入门

0.开始 教学视频出处 https://www.bilibili.com/video/BV1w84y1z77V?p3&spm_id_frompageDriver&vd_source0f7f337dd5a99bb975b88a48ae1b3711 日期:2022/12/3 rollup目前版本: "rollup": "^3.5.1"1.rollup概述 官网 http…

N32G45之串口+DMA数据收发

N32G45之串口DMA数据收发 1.串口简介   通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。 USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LI…

【云原生】nacos权限制认证

鉴权 服务端如何开启鉴权 非Docker环境 按照官方文档配置启动,默认是不需要登录的,这样会导致配置中心对外直接暴露。而启用鉴权之后,需要在使用用户名和密码登录之后,才能正常使用nacos。 开启鉴权之前,application.properti…

0115 查找算法Day4

剑指 Offer 03. 数组中重复的数字 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例 1: …

Linux-CPU之平均负载

一般我们觉得系统变慢了,都会执行 top 或者 uptime 命令,来了解系统的负载情况。 uptime11:29:06 up 0 min, 2 users, load average: 1.21, 0.29, 0.10// 当前时间 // 系统运行时间 // 正在登录用户数 //1 分钟、5 分钟、15 分钟的平均负载概念&…

补知识点:Stream API

一、创建Stream 首先创建Stream的话,有四种创建方式: 注: 第一种集合的方式是最常用的 package com.atguigu.gulimall.gateway;import com.atguigu.gulimall.streamapi.Employee; import com.atguigu.gulimall.streamapi.EmployeeData; impo…

【应用】Docker

DockerDocker 的安装基本安装流程配置镜像加速Docker 常用命令镜像相关命令容器相关命令DockerfileDockerfile 常用指令Dockerfile 简单使用案例Dockerfile 构建 java 项目镜像Docker ComposeDocker compose 基本参数services 配置参数Docker 的安装 基本安装流程 使用虚拟机…

Linux JDK8下载安装

JDK安装 整体步骤介绍 操作步骤: 1 查看自己linux版本位 getconf LONG_BIT(64位) 2. 下载jdk的安装包 这里提供三种方法下载: (以jdk-8u171-linux-x64.tar.gz为例) 2.1 官网下载jdk: 官网: https://www.oracle.com/downloads/ jdk最新版本下载: https://www.oracle.com…

带你玩转序列模型之seq2seq模型定向(集束)搜索

目录 一.基础模型 二.选择最可能的句子 三.定向搜索 四.改进定向搜索 五.定向搜索的误差分析 一.基础模型 在这一周,你将会学习seq2seq(sequence to sequence)模型,从机器翻译到语音识别,它们都能起到很大的作用…

【数据结构1】数据结构的基本概念

数据结构的基本概念 数据:数据是信息的载体,是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 数据元素、数据项:数据元素是数据的基本单位,通常作为一…