当前位置: 首页 > news >正文

malloc实现原理探究

       2021年末面试蔚来汽车,面试官考察了malloc/free的实现机制。当时看过相关的文章,有一点印象,稍微说了一点东西,不过自己感到不满意。今天尝试研究malloc的实现细节,看了几篇博文,发现众说纷纭,且实现比较复杂。在此,对malloc的实现机制进行研究,了解其大概的工作机制,没有深究细节。

先说结论:

内存的分配:

可以把内存空间的分配分为两个过程:

1)从操作系统获取到内存,实际获取到的内存一般比进程申请的空间大一些。

2)从申请到的空间中拿出来一部分给到进程。

所以,一般会有部分备用的内存空间。所以,就有了下面的结论。

1.如果进程申请的空间小于备用的空间,则直接把内存分配给进程。

2.如果进程申请的空间大于备用的空间,

1)申请的空间<128KB,通过系统调用brk在现有地址的基础上扩张,即新分配的空间和之前的空间是连续的。

2)申请的空间>128KB,通过mmap在物理内存映射一段空间。

内存的释放:

试验环境:ubuntu虚拟机,gcc:Ubuntu 9.4.0-1ubuntu1~20.04.1

测试代码:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>typedef unsigned char uint8;int main()
{//step1getchar();uint8* p1 = (uint8*)malloc(127 * 1024 * sizeof(uint8));printf("p1:%p,size:%ld\n", p1, malloc_usable_size(p1));//step2getchar();free(p1);//step3getchar();uint8* p2 = (uint8*)malloc(127 * 1024 * sizeof(uint8));printf("p2:%p,size:%ld\n", p2, malloc_usable_size(p2));//step4getchar();uint8* p3 = (uint8*)malloc(127 * 1024 * sizeof(uint8));printf("p3:%p,size:%ld\n", p3, malloc_usable_size(p2));//step5getchar();uint8* p4 = (uint8*)malloc(500 * 1024 * sizeof(uint8));printf("p4:%p,size:%ld\n", p4, malloc_usable_size(p4));//step6getchar();uint8* p5 = (uint8*)malloc(1024 * sizeof(uint8));printf("p5:%p,size:%ld\n", p5, malloc_usable_size(p5));//step7getchar();free(p5);//step8getchar();free(p4);getchar();return 0;
}

测试方法:

1.通过strace跟踪进程执行的过程。

2.通过cat /proc/PID/maps观察堆区的分配情况。

测试过程和分析:

strace ./a.out

brk(NULL)                               = 0x55c726c6e000
brk(0x55c726c8f000)              = 0x55c726c8f000
//进程启动之后,系统自动分配了0x55c726c8f000-0x55c726c6e000,约为400K的内存,这部分内存,是备用的。

//step1:55c726c6e000-55c726c8f000 [heap]
//进程请求分配127K内存,由于系统已有400K空余的内存,够用,所以,直接给进程返回一块内存。起始地址为p1=0x55c726c6e6b0,和预留的起始地址相比,有一定的偏移量
read(0, 
"\n", 1024)                     = 1
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
write(1, "p1:0x55c726c6e6b0,size:130056\n", 30p1:0x55c726c6e6b0,size:130056
) = 30

//step2:55c726c6e000-55c726c8f000 [heap]
//free(p1),系统只是把这块空间标记为可用的,并没有真正的释放其内存空间。
read(0, 
"\n", 1024)                     = 1

//step3:55c726c6e000-55c726c8f000 [heap]
//再次请求分配127K的内存,备用的内存空间够用,同step1,直接分配给进程。
read(0, 
"\n", 1024)                     = 1
write(1, "p2:0x55c726c6e6b0,size:130056\n", 30p2:0x55c726c6e6b0,size:130056
) = 30

//step4:55c726c6e000-55c726ccf000 [heap]
//再次请求分配129K的内存空间,之前剩余的备用空间约为400K-127K-127K=146K,不够用了。而且,请求分配的内存<128K,在原来地址的基础上,通过brk扩充内存空间,即和原来的内存是连续的
read(0, 
"\n", 1024)                     = 1
brk(0x55c726ccf000)                     = 0x55c726ccf000
write(1, "p3:0x55c726c8e6d0,size:130056\n", 30p3:0x55c726c8e6d0,size:130056
) = 30

//step5
//55c726c6e000-55c726ccf000 [heap]
//f2b3313f000-7f2b331bd000 
//再次请求分配500K的内存空间,之前剩余的备用空间不够用了,而且,请求分配的内存>128K,通过mmap在物理内存映射一块空间,且和原来的空间是不连续的
read(0, 
"\n", 1024)                     = 1
mmap(NULL, 516096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2b3313f000
write(1, "p4:0x7f2b3313f010,size:516080\n", 30p4:0x7f2b3313f010,size:516080
) = 28

//step6
//55c726c6e000-55c726ccf000 [heap]
//f2b3313f000-7f2b331bd000 
//同step1
read(0, 
"\n", 1024)                     = 1
<pre>write(1, &quot;p5:0x55c726cae2e0,size:1032\n&quot;, 28p5:0x55c726cae2e0,size:1032</pre>

//step7
//55c726c6e000-55c726ccf000 [heap]
//f2b3313f000-7f2b331bd000 
//同step2
read(0, 
"\n", 1024)                     = 1

//step8:55c726c6e000-55c726ccf000 [heap]
//通过munmap释放内存
read(0, 
"\n", 1024)                     = 1
munmap(0x7f2b3313f000, 516096)

相关文章:

malloc实现原理探究

2021年末面试蔚来汽车&#xff0c;面试官考察了malloc/free的实现机制。当时看过相关的文章&#xff0c;有一点印象&#xff0c;稍微说了一点东西&#xff0c;不过自己感到不满意。今天尝试研究malloc的实现细节&#xff0c;看了几篇博文&#xff0c;发现众说纷纭&#xff0c;且…...

Spring——整合junit4、junit5使用方法

spring需要创建spring容器&#xff0c;每次创建容器单元测试是测试单元代码junit4依赖<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…...

计算机网络的一些思考(待完善)

文章目录概念1. 缓存2. 备份&#xff08;副本&#xff09;3. 硬件和软件&#xff1a;4.端口5. 二进制协议vs文本协议6. 虚拟7.分布式8.广播域和冲突域的区别9本地地址协议1.CSMA/CD协议2.IP协议3.路由算法协议&#xff08;RIP&#xff0c;OSPF&#xff0c;BGP&#xff09;4.ARP…...

【第一章】谭浩强C语言课后习题答案

1.什么是程序?什么是程序设计? 程序:就是一组能识别和执行的指令,每一条指令使计算机执行特定的操作 程序设计:是指从确定任务到得到结果、写出文档的全过程 2.为什么需要计算机语言?高级语言有哪些特点? 为什么需要计算机语言:计算机语言解决了人和计算机交流是的…...

最新版本vue3+vite重构尚品汇(解决接口问题)第21-50集

第21集&#xff0c;第22集&#xff1a;照敲就行&#xff0c;引入概念。 第23集&#xff1a;防抖概念&#xff1a;前面所有的触发被取消&#xff0c;最后一次执行在规定的时间之后才会触发&#xff0c;只会执行一次。Lodash插件里面封装了函数的防抖和节流的业务。用到lodash确实…...

【超级猜图案例上半部分的实现 Objective-C语言】

一、超级猜图这么一个案例: 1.实现之后的效果是这样的: 1)中间有一个图片,点一下,能放大,背景变半透明的黑色: 2)再点一下图片,或者点周围黑色的阴影,图片回归原状, 3)右边有一个“大图”按钮,点一下,实现跟点图片一样的效果, 4)左边有一个“提示”按钮,点…...

刷题笔记4 | 24. 两两交换链表中的节点、19. 删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II

24. 两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 输入&#xff1a;head [1,2,3,4] 输出&#xff1a…...

15、正则表达式

目录 一、元字符 二、限定修饰符 一、元字符 正则表达式通常被用于判断语句中&#xff0c;用来检查某一字符串是否满足某一格式。正则表达式是含有一些具有特殊意义字符的字符串&#xff0c;这些特殊字符称为正则表达式的元字符。例如&#xff0c;“\\d”表示数字0~9中的任何…...

javaWeb核心01-HTTPTomcatServlet

文章目录HTTP&Tomcat&Servlet1&#xff0c;Web概述1.1 Web和JavaWeb的概念1.2 JavaWeb技术栈1.2.1 B/S架构1.2.2 静态资源1.2.3 动态资源1.2.4 数据库1.2.5 HTTP协议1.2.6 Web服务器1.3 Web核心课程安排2, HTTP2.1 简介2.2 请求数据格式2.2.1 格式介绍2.2.2 实例演示2.…...

深圳大学计软《面向对象的程序设计》实验16 期末复习

A. 一、会员积分&#xff08;期末模拟&#xff09; 题目描述 某电商网站的会员分为&#xff1a;普通、贵宾两个级别 普通会员类Member&#xff0c;包含编号、姓名、积分三个属性&#xff0c;编号和积分是整数&#xff0c;姓名是字符串 操作包括构造、打印、积分累加、积分兑…...

Linux基础命令(一)

文章目录1、时间命令&#xff1a;date2、日历命令&#xff1a;cal3、计算器程序&#xff1a;bc4、基础组合键5、正确的关机指令使用5.1 将数据同步写入硬盘中的指令&#xff1a; sync5.2 惯用的关机指令&#xff1a; shutdown5.3 重新开机&#xff0c;关机&#xff1a; reboot,…...

RocketMQ Broker消息处理流程剩余源码解析

&#x1f34a; Java学习&#xff1a;Java从入门到精通总结 &#x1f34a; 深入浅出RocketMQ设计思想&#xff1a;深入浅出RocketMQ设计思想 &#x1f34a; 绝对不一样的职场干货&#xff1a;大厂最佳实践经验指南 &#x1f4c6; 最近更新&#xff1a;2023年3月4日 &#x1…...

JQuery入门基础

目录 1.初识 下载 使用 JQuery&#xff08;核心&#xff09;对象 2.选择器 基础选择器 层次选择器 后代选择器 子代选择器 兄弟选择器 相邻选择器 3.JQuery DOM操作 创建元素 插入元素 删除元素 遍历元素 属性操作 获取属性 设置属性 删除属性 样式操作 …...

kafka 构建双向SSL认证

kafka 安装 以下内容均已完成测试&#xff0c;按照教程搭建你会得到一个双向ssl认证的kafka broker&#xff0c;并能通过ip以及域名访问&#xff0c;笔者能力有限如果文章内容存在问题烦请各位指出。 搭建单机Kafka 需求 centos 7kafka_2.12-2.6.0jdk8&#xff08;文档中统…...

推荐一个.Net Core开发的Websocket群聊、私聊的开源项目

更多开源项目请查看&#xff1a;一个专注推荐.Net开源项目的榜单 今天给大家推荐一个使用Websocket协议实现的、高性能即时聊天组件&#xff0c;可用于群聊、好友聊天、游戏直播等场景。 项目简介 这是一个基于.Net Core开发的、简单、高性能的通讯组件&#xff0c;支持点对点…...

华为OD机试Golang解题 - 事件推送 | 含思路

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典文章目录 华为Od必看系列使用说明本期题目…...

将微信小程序页面转为图片

最近做项目遇到一个需求,那就是要将某个页面转为图片然后传给后端,我仔细找了一圈,发现官方那个Api也就是wx.canvasToTempFilePath生成的图片很有可能为空,太坑了,于是我放弃用它了,选择了用wxml2canvas。 安装wxml2canvas npm init npm install wxml2canvas --save --…...

LINE、SDNE和struc2vec图嵌入算法学习笔记

引言 在cs224w课程中&#xff0c;我先后总结了deepwalk、node2vec&#xff0c;这两种算是最经典也是最主流的做法&#xff0c;而在 图节点嵌入相关算法学习笔记 中&#xff0c;从头至尾&#xff0c;将一些经典算法用wiki的数据集复现了一下&#xff0c;所以本篇博文&#xff0…...

Buuctf Younger-drive 题解

目录 一.查壳 二.运行缺少dll 三.主函数 四.hObject线程 五.Thread线程 六.judge函数 七.解题脚本 这题的关键在于了解一定的线程相关知识 一.查壳 32位带壳,用upx脱壳 二.运行缺少dll 后续尝试了各种方法修复dll但是还是运行不了 值得一提的是脱壳后的程序不能动态调试…...

数据结构与算法:二叉树专题

数据结构与算法&#xff1a;二叉树专题前言前提条件基础知识二叉树链式存储结构二叉树中序遍历二叉树层序遍历常见编程题把一个有序整数数组放到二叉树中逐层打印二叉树结点数据求一棵二叉树的最大子树和判断两棵二叉树是否相等把二叉树转换为双向链表判断一个数组是否是二元查…...

【开题答辩全过程】以 校园创新创业管理系统设计与实现为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…...

SKILL语言在数字IC设计中的高级应用:如何优化你的工作流程

SKILL语言在数字IC设计中的高级应用&#xff1a;如何优化你的工作流程 在数字IC设计的复杂世界里&#xff0c;效率就是竞争力。当大多数工程师还在手动点击EDA工具菜单时&#xff0c;掌握SKILL语言的高手已经用几行代码完成了批量操作。这不是魔法&#xff0c;而是SKILL语言赋…...

原神抽卡数据分析工具:智能解析与可视化全攻略

原神抽卡数据分析工具&#xff1a;智能解析与可视化全攻略 【免费下载链接】genshin-wish-export biuuu/genshin-wish-export - 一个使用Electron制作的原神祈愿记录导出工具&#xff0c;它可以通过读取游戏日志或代理模式获取访问游戏祈愿记录API所需的authKey。 项目地址: …...

宝塔面板计划任务设置教程

宝塔面板的计划任务&#xff0c;就是服务器的定时执行工具&#xff0c;不用手动敲命令&#xff0c;可视化界面就能设置&#xff0c;能实现自动备份、定时重启、清理缓存、执行脚本等多种自动化操作。下面详细讲解完整设置步骤、常用任务配置和避坑技巧。一、进入计划任务页面1.…...

C语言数组操作:3种移除元素方法实战对比(附LeetCode真题解析)

C语言数组操作&#xff1a;3种移除元素方法实战对比&#xff08;附LeetCode真题解析&#xff09; 在算法面试和日常编程中&#xff0c;数组操作是最基础也最常考察的技能点之一。移除数组中特定元素这类看似简单的任务&#xff0c;却能很好地检验程序员对内存管理、算法效率和…...

基于uniapp的SUPOIN PDA激光扫码广播监听功能实现与优化

1. 为什么选择SUPOIN PDA激光扫码方案 在工业级移动应用中&#xff0c;扫码功能可以说是刚需中的刚需。我做过不少仓库管理、物流配送的项目&#xff0c;深刻体会到扫码速度差个0.5秒&#xff0c;工人一天下来就能多处理上百件货物。SUPOIN PDA设备自带的激光扫码模块&#xf…...

企业软件底层逻辑脱胎换骨:从席位订阅到决策订阅,下一个万亿公司属于这类玩家

允中 发自 凹非寺量子位 | 公众号 QbitAI大模型落地进入深水区&#xff0c;企业级软件正在发生一次底层逻辑的“脱胎换骨”。回顾技术发展史&#xff0c;ERP、CRM、BI的出现&#xff0c;本质上是在解决资源、客户与数据的“管理”问题。在此背景下&#xff0c;由哈佛大学博士、…...

MySQL视图与子查询的那些事儿:从报错1349看数据库设计的最佳实践

MySQL视图与子查询深度解析&#xff1a;从报错1349看高效数据库设计 在数据库开发与维护过程中&#xff0c;视图(View)和子查询(Subquery)是两种极为常用的技术手段。它们能够简化复杂查询、提高代码复用性&#xff0c;并为数据安全提供额外保障。然而&#xff0c;当这两种技术…...

3分钟解锁你的音乐收藏:qmc-decoder让QQ音乐加密格式不再受限

3分钟解锁你的音乐收藏&#xff1a;qmc-decoder让QQ音乐加密格式不再受限 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder 你是否曾经下载过QQ音乐的歌曲&#xff0c;却发现…...

ssm+java2026年毕设桃花新村社区【源码+论文】

本系统&#xff08;程序源码&#xff09;带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、选题背景关于新闻资讯管理系统的研究&#xff0c;现有研究主要以传统门户网站的新闻发布系统为主&#xff0c;专门针对中小型组织、企业…...