ptmalloc源码分析 - _int_malloc函数实现fastbins(06)

news2024/10/6 4:01:18

目录

一、_int_malloc内存分配的核心函数

二、bins的管理和chunk的结构

三、_int_malloc函数分配前的两个检查

四、REMOVE_FB原子实现fastbins的链表操作

五、fastbins的具体分配实现


一、_int_malloc内存分配的核心函数


前几章节,我们主要讲解了状态机malloc_state、内存组织单元malloc_chunk、分配区Arena三个概念。此处有必要再次再次加强这几个概念的理解:

  • 状态机:是指malloc_state这个数据结构,该结构用来管理分配区下面的内存组织结构,例如:fastbins、smallbins、largebins等。通过状态机,我们就能找到对应的内存应该在那个bins上分配
  • 内存组织单元:是指malloc_chunk这个数据结构,该结构主要管理每一次分配的内存,chunk分为数据记录区和数据区,通过chunk我们也能将不同的chunk进行双向链表放置到不同的bins上
  • 分配区:分配区分为主分配区和非主分配区,主要为了避免多线程争抢。

内存是如何分配的,以及如何将分配的内存关联到malloc_chunk,然后放置到malloc_state的状态机上,则是由_int_malloc函数实现的。

我们继续回到入口函数__libc_malloc :

  • 首选通过arena_get函数,获取一个分配区,得到ar_ptr的值(也是当前分配区状态机malloc_state)
  • 然后调用_int_malloc函数,传入ar_ptr和bytes参数,最终得到victim值,即malloc_chunk这个结构
  • 如果victim的值为NULL,分配失败,则调用arean_get_retry重新获取一个新的分配区,并重新执行_int_malloc函数
  /* 获取一个分配区,分配区分为主分配区和线程分配区 ,并加锁*/
  arena_get (ar_ptr, bytes);

  /* 执行malloc的分配操作 */
  victim = _int_malloc (ar_ptr, bytes);
  /* Retry with another arena only if we were able to find a usable arena
     before. 如果执行分配失败,则再执行一遍 */
  if (!victim && ar_ptr != NULL)
    {
      LIBC_PROBE (memory_malloc_retry, 1, bytes);
      ar_ptr = arena_get_retry (ar_ptr, bytes); //重新获取分配区
      victim = _int_malloc (ar_ptr, bytes);
    }

  /* 解除锁;arena_get函数里面,如果分配区能够取到,则会上锁 */
  if (ar_ptr != NULL)
    __libc_lock_unlock (ar_ptr->mutex);

  assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
          ar_ptr == arena_for_chunk (mem2chunk (victim)));
  return victim;
}

二、bins的管理和chunk的结构


这一节还是要继续回顾一下bins的管理方式和chunk的结构。这个比较重要,后续会贯穿整个_int_malloc的实现。

bins的实现

在malloc_state状态机里面,有两个结构对象:fastbinsY和bins

fastbinsY:fast bins是bins的高速缓冲区,大约有10个定长队列。当用户释放一块不大于max_fast(默认值64)的chunk(一般小内存)的时候,会默认会被放到fast bins上。

bins:主要管理small bins、large bins、unstored bins,在一个数组上,通过数组下标和步长方式来区分不同类型的bins

 

chunk实现:

 malloc_chunk结构主要管理了chunk的大小,双向链表的指针以及空闲链表的指针等。通过chunk结构也能获取到实际存储的数据区域。

三、_int_malloc函数分配前的两个检查


_int_malloc入参mstate av和size_t bytes,即分配区状态机结构和内存分配的大小。

分配前需要做两个检查:

  • 检查bytes是否在合法区间内,最大小于<2147483647

  • 如果分配区结构为空,则调用sysmalloc进行再次分配

/**
 * malloc的核心分配函数
 * av:分配区
 * bytes:内存的大小
 */
static void *
_int_malloc (mstate av, size_t bytes)
{

........

  //检查bytes是否在合法区间内,最大小于<2147483647
  if (!checked_request2size (bytes, &nb))
    {
      __set_errno (ENOMEM);
      return NULL;
    }

  /* There are no usable arenas.  Fall back to sysmalloc to get a chunk from
     mmap.  */
  /* 如果分配区结构为空,则调用sysmalloc进行再次分配 */
  if (__glibc_unlikely (av == NULL))
    {
      void *p = sysmalloc (nb, av);
      if (p != NULL)
	alloc_perturb (p, bytes);
      return p;
    }

四、REMOVE_FB原子实现fastbins的链表操作


定义了一个REMOVE_FB宏函数,该函数主要目的: 原子操作,从fast bins链表上,弹出一个chunk

因为fastbinsY是一个数组,数组上挂载malloc_chunk是双向链表,当多线程进行同时操作链表的时候就会冲突,需要进行原子操作

核心看该函数:define catomic_compare_and_exchange_val_acq(mem, newval, oldval),mem指向newval,并且返回oldval的值

/*
 * 该函数就是原子操作,从fast bins链表上,弹出一个chunk
 *
 * 核心看该函数:
 * define catomic_compare_and_exchange_val_acq(mem, newval, oldval)
 * mem指向newval,并且返回oldval的值
 * */
#define REMOVE_FB(fb, victim, pp)			\
  do							\
    {							\
      victim = pp;					\
      if (victim == NULL)				\
	break;						\
    }							\
  while ((pp = catomic_compare_and_exchange_val_acq (fb, victim->fd, victim)) \
	 != victim);	

五、fastbins的具体分配实现


fastbins放置在malloc_state-> fastbinsY数组上,是高速缓冲区(主要用于小内存的快速分配和释放),大约有10个定长队列。

当用户释放一块不大于max_fast(默认值64)的chunk(一般小内存)的时候,会默认会被放到fast bins上。

_int_malloc函数中,先看申请的内存大小nb是否符合fast bins的限制,符合的话,首先进入fast bin的分配。

  if ((unsigned long) (nb) <= (unsigned long) (get_max_fast ()))
    {
      idx = fastbin_index (nb); //找到fastbin的数组下标idx
      mfastbinptr *fb = &fastbin (av, idx); //av->fastbinsY[idx]
      mchunkptr pp;
      victim = *fb; //vitctim是malloc_chunk结构

      /* 如果在fastbin上能够找到空闲的小于64b的chunk,则使用该chunk;
       * 如果在fastbin上没有合适的chunk,则去下面的small bins上去创建一个chunk */
      if (victim != NULL)
	{
	  if (SINGLE_THREAD_P)
	    *fb = victim->fd; //单线程
	  else
	    REMOVE_FB (fb, pp, victim); //设置 原子操作,将chunk从fast bins上摘下来,多线程的时候会争抢

	  /* REMOVE_FB是原子操作,所以这里需要继续判断一下,是否摘成功了,victim是否有值*/
	  if (__glibc_likely (victim != NULL))
	    {
	      size_t victim_idx = fastbin_index (chunksize (victim));
	      if (__builtin_expect (victim_idx != idx, 0))
		malloc_printerr ("malloc(): memory corruption (fast)");
	      check_remalloced_chunk (av, victim, nb);

..........................简.............

	      void *p = chunk2mem (victim); //通过chunk结构,获取data数据部分的指针地址
	      alloc_perturb (p, bytes); //初始化内存块
	      return p;
	    }
	}
    }

下一章节,我们继续看_int_malloc函数里面的smallbins、largebins实现

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

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

相关文章

xml

1.xml 1.1概述【理解】 万维网联盟(W3C) 万维网联盟(W3C)创建于1994年&#xff0c;又称W3C理事会。1994年10月在麻省理工学院计算机科学实验室成立。 建立者&#xff1a; Tim Berners-Lee (蒂姆伯纳斯李)。 是Web技术领域最具权威和影响力的国际中立性技术标准机构。 到目前为…

nginx反向代理 负载均衡

一、反向代理&#xff1a; 1.反向代理介绍&#xff1a; 反向代理&#xff1a;reverse proxy&#xff0c;指的是代理外网用户的请求到内部的指定的服务器&#xff0c;并将数据返回给用户的一种方式&#xff0c;这是用的比较多的一种方式。 Nginx 除了可以在企业提供高性能的web…

从2023蓝帽杯0解题heapSpary入门堆喷

从2023蓝帽杯0解题heapSpary入门堆喷 关于堆喷 堆喷射&#xff08;Heap Spraying&#xff09;是一种计算机安全攻击技术&#xff0c;它旨在在进程的堆中创建多个包含恶意负载的内存块。这种技术允许攻击者避免需要知道负载确切的内存地址&#xff0c;因为通过广泛地“喷射”堆…

三路排序算法(Java 实例代码)

目录 三路排序算法 一、概念及其介绍 二、适用说明 四、Java 实例代码 QuickSort3Ways.java 文件代码&#xff1a; 三路排序算法 一、概念及其介绍 三路快速排序是双路快速排序的进一步改进版本&#xff0c;三路排序算法把排序的数据分为三部分&#xff0c;分别为小于 v&…

blender 火焰粒子

效果展示 创建火焰模型 新建立方体&#xff08;shift A &#xff09;,添加表面细分修改器&#xff08;ctrl 2 &#xff09;&#xff0c;视图层级调整为 3 &#xff0c;这样布线更密集&#xff1b; 右键将模型转换为网格&#xff0c;tab 进入编辑模式&#xff0c;7 切换到顶…

基于 Debian 12 的 Devuan GNU+Linux 5 为软件自由爱好者而生

导读Devuan 开发人员宣布发布 Devuan GNULinux 5.0 “代达罗斯 “发行版&#xff0c;它是 Debian GNU/Linux 操作系统的 100% 衍生版本&#xff0c;不包含 systemd 和相关组件。 Devuan GNULinux 5 基于最新的 Debian GNU/Linux 12 “书虫 “操作系统系列&#xff0c;采用长期支…

Kafka3.0.0版本——手动调整分区副本示例

目录 一、服务器信息二、启动zookeeper和kafka集群2.1、先启动zookeeper集群2.2、再启动kafka集群 三、手动调整分区副本3.1、手动调整分区副本的前提条件3.2、手动调整分区副本的示例需求3.3、手动调整分区副本的示例 一、服务器信息 四台服务器 原始服务器名称原始服务器ip节…

新型安卓恶意软件使用Protobuf协议窃取用户数据

近日有研究人员发现&#xff0c;MMRat新型安卓银行恶意软件利用protobuf 数据序列化这种罕见的通信方法入侵设备窃取数据。 趋势科技最早是在2023年6月底首次发现了MMRat&#xff0c;它主要针对东南亚用户&#xff0c;在VirusTotal等反病毒扫描服务中一直未被发现。 虽然研究…

Linux--VMware的安装和Centos

一、VMware和Linux的关系 二、VMware的安装 VM_ware桌面虚拟机 最新中文版 软件下载 (weizhen66.cn) VMware-Workstation-Lite-16.2.2-19200509-精简安装注册版.7z - 蓝奏云 如果安装不成功&#xff0c;则设置BIOS 三、在VMware中加入Centos 下载地址&#xff1a; CentOS-…

深度学习论文分享(八)Learning Event-Driven Video Deblurring and Interpolation

深度学习论文分享&#xff08;八&#xff09;Learning Event-Driven Video Deblurring and Interpolation 前言Abstract1 Introduction2 Motivation2.1 Physical Model of Event-based Video Reconstruction2.2 Spatially Variant Triggering Threshold 3 Proposed Methods3.1 …

初学者如何制作属于自己的第一个网页?

如今&#xff0c;网页设计已经成为互联网世界不可或缺的一部分。随着网络的发展&#xff0c;越来越多的用户通过网页浏览信息、社交和购物。一个出色的网页设计能吸引用户的眼球&#xff0c;提升他们的浏览体验&#xff0c;从而提高用户满意度和忠诚度。那么&#xff0c;要设计…

机器学习——手写数字识别

0、&#xff1a;前言 这篇文章能够帮助你从数据到模型的整个过程实现不过至于安装第三方库等基础问题&#xff0c;本文不涉及&#xff0c;因为确实不难&#xff0c;搜一搜一大把本此实验运行环境为jupyter&#xff0c;当然通过pycharm也是可行的 1、数据&#xff1a; 手写数字…

简单了解网络基本概念

目录 一、网络含义 二、什么是以太网&#xff1f; 三、网络分类 四、网络架构 五、数据传输方式 六、双工模式 一、网络含义 在实际生活中我们用传输介质把独立的终端设备相互连接起来就构成了网络。 二、什么是以太网&#xff1f; 以太网是一种网络通信协议标准&#…

浅谈 Pytest+HttpRunner 如何展开接口测试!

软件测试有多种多样的方法和技术&#xff0c;可以从不同角度对它们进行分类。其中&#xff0c;根据软件生命周期&#xff0c;针对不同的测试对象与目标&#xff0c;可将测试过程分为 4 个阶段&#xff1a;单元测试、集成测试、系统测试和验收测试。本文着重介绍了如何借用 pyte…

【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之数码管静态显示(四)

本原创教程由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处 适用于板卡型号&#xff1a; 紫光同创PGL22G开发平台&#xff08;盘古22K&#xff09; 一&#xff1a;盘古22K开发板&#xff08;紫光同创PGL22G开发…

postgresql-集合运算

postgresql-集合运算 简介UNIONINTERSECTEXCEPT分组与排序集合操作优先级 简介 数据库中的表&#xff08;table&#xff09;本质上就是由行&#xff08;row&#xff09;组成的集合。因此&#xff0c;PostgreSQL 同样支持集 合论中的集合操作&#xff0c;包括并集&#xff08;U…

CSS中的相对单位和绝对单位,以及rem自适应布局

在CSS中&#xff0c;我们经常需要指定元素的尺寸、间距和位置。为此&#xff0c;我们可以使用各种单位来定义这些值。本文将重点介绍CSS中的相对单位和绝对单位&#xff0c;并解释它们之间的区别。 相对单位 百分比&#xff08;%&#xff09;&#xff1a;百分比单位是相对于父元…

Go 官方标准编译器中所做的优化

本文是对#102 Go 官方标准编译器中实现的优化集锦汇总[1] 内容的记录与总结. 优化1-4: 字符串和字节切片之间的转化 1.紧跟range关键字的 从字符串到字节切片的转换&#xff1b; package mainimport ( "fmt" "strings" "testing")var cs10086 s…

C#里Bitmap转Halocn的HObject

一般情况下&#xff0c;图像的width是4的倍数的话&#xff0c;用以下代码便可将彩色bitmap转出halcon里的HObject public void Bitmap2HObject(Bitmap bmp, out HObject image){try{Rectangle rect new Rectangle(0, 0, bmp.Width, bmp.Height);BitmapData srcBmpData bmp.L…

通讯录管理系统(个人学习笔记黑马学习)

1、系统需求 通讯录是一个可以记录亲人、好友信息的工具。 本教程主要利用C来实现一个通讯录管理系统系统中需要实现的功能如下: 添加联系人:向通讯录中添加新人&#xff0c;信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人显示联系人:显示通讯录中所有联系人信…