ptmalloc源码分析 - malloc/free函数的实战篇(12)
目录
一、chunk的大小实验
二、获取使用中的chunk信息的实验
三、小内存块尝试获取fd信息的实验
四、常用malloc/free函数使用注意事项
看了前面11章节的内容,我们也基本了解了ptmalloc的内存管理逻辑。此处也可以通过一些手段,获取到chunk的信息,可以来实战实验一把。
一、chunk的大小实验
在《ptmalloc源码分析 - 内存组织单元malloc_chunk(03)》章里面我们讲解了chunk的数据结构和大小:
- chunk在使用中的时候,只使用mchunk_prev_size和mchunk_size两个字段
- chunk在空闲的时候,会复用用户空间,存储fd/bk/fd_nextsize/bk_nextsize,用户空间最小是16字节
- chunk主要存储mchunk_prev_size和mchunk_size两个字段,所以chunk的结构体8个字段就能满足
- 每次分配的大小:(16字节 + 分配的内存) & 进行2*SIZE_SZ对齐(64位系统是16字节/32位系统8字节)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>int main() {char *s = NULL;s = (char *) malloc (23 * sizeof(char));char *p = NULL;p = (char *) malloc (25 * sizeof(char));char *p1 = NULL;p1 = (char *) malloc (110 * sizeof(char));printf("s : %d\r\n", s);printf("p : %d\r\n", p);printf("p1 : %d\r\n", p1);
}
结果:
$./main
s : 6299664
p : 6299696
p1 : 6299744/****************/
s的值:23 + 8 = 31 & 16 = 32
p的值:25 + 8 = 33 & 16 = 48
二、获取使用中的chunk信息的实验
我们将malloc_chunk的结构拷贝过来,以及mem2chunk/chunk2men/chunksize等几个宏定义也拷贝过来。
这样,我们可以通过mem2chunk的方式,获取得到chunk的对象指针地址。因为当前chunk在使用中,所以可以获取得到mchunk_size的值了。
由于mchunk_size字段的最后三个bit位,复用用作了(AMP)的标记位置。后三位bit位的复用,不会影响size的数据大小。所以直接取mchunk_size的时候是带上了AMP的标记数据。通过chunksize的方式,可以获得真正的chunk size数据。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>struct malloc_chunk {size_t mchunk_prev_size; /* Size of previous chunk (if free). */size_t mchunk_size; /* 当前chunk的大小 Size in bytes, including overhead. */struct malloc_chunk* fd; /* double links -- used only if free. */struct malloc_chunk* bk;struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */struct malloc_chunk* bk_nextsize;
};
typedef struct malloc_chunk* mchunkptr;
#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*sizeof(size_t)));
#define chunk2mem(p) ((void*)((char*)(p) + 2*sizeof(size_t)));
#define chunksize_nomask(p) ((p)->mchunk_size)
#define chunksize(p) (chunksize_nomask (p) & ~(0x1|0x2|0x4))int main() {char *s = NULL;s = (char *) malloc (23 * sizeof(char));char *p = NULL;p = (char *) malloc (25 * sizeof(char));char *p1 = NULL;p1 = (char *) malloc (110 * sizeof(char));printf("s : %d\r\n", s);printf("p : %d\r\n", p);printf("p1 : %d\r\n", p1);printf("size:%d\r\n", sizeof(mchunkptr));mchunkptr pr = mem2chunk(p);printf("p chunk_size value:%d\r\n", pr->mchunk_size);printf("p chunk size:%d\r\n", chunksize(pr));}
结果:
$./main
s : 6299664
p : 6299696
p1 : 6299744
size:8
p chunk_size value:49
p chunk size:48
三、小内存块尝试获取fd信息的实验
我们分配一组小内存块,可以尝试将部分内存直接free。小内存块分配是是落在fastbin上的,这些内存块没有经过合并整理的操作,所以我们可以尝试从已经被free的chunk中获取得到一些信息,例如chunk->fd指针信息等。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>struct malloc_chunk {size_t mchunk_prev_size; /* Size of previous chunk (if free). */size_t mchunk_size; /* 当前chunk的大小 Size in bytes, including overhead. */struct malloc_chunk* fd; /* double links -- used only if free. */struct malloc_chunk* bk;struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */struct malloc_chunk* bk_nextsize;
};
typedef struct malloc_chunk* mchunkptr;
#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*sizeof(size_t)));
#define chunk2mem(p) ((void*)((char*)(p) + 2*sizeof(size_t)));
#define chunksize_nomask(p) ((p)->mchunk_size)
#define chunksize(p) (chunksize_nomask (p) & ~(0x1|0x2|0x4))
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
#define request2size(req) (((req) + 8 + 15 < 32) ? 32 : ((req) + 8 + 15) & ~15)int main() {malloc(20*sizeof(char));char *a1 =(char *) malloc(26*sizeof(char));char *a2 =(char *) malloc(27*sizeof(char));char *a3 =(char *) malloc (26 * sizeof(char));malloc(20*sizeof(char));/* 获取内存分配地址 */printf("a1 : %d\r\n", a1);printf("a2 : %d\r\n", a2);printf("a3 : %d\r\n", a3);/* 获取chunk 指针 */mchunkptr a1pr = mem2chunk(a1);mchunkptr a2pr = mem2chunk(a2);mchunkptr a3pr = mem2chunk(a3);printf("a1 chunk:%d\r\n", a1pr);printf("a2 chunk:%d\r\n", a2pr);printf("a3 chunk:%d\r\n", a3pr);/* 获取a2的chunk数据 */printf("p chunk_size value:%d\r\n", a2pr->mchunk_size);printf("p chunk size:%d\r\n", chunksize(a2pr));/* 执行free操作 */free(a1);free(a2);free(a3);printf("free a1 mchunk_size value:%d\r\n", a1pr->mchunk_size); //获取free掉的chunk的size,在fastbin上printf("free a2 fd value:%d\r\n", a2pr->fd);printf("free a3 fd value:%d\r\n", a3pr->fd);}
$./main
a1 : 6299696
a2 : 6299744
a3 : 6299792
a1 chunk:6299680
a2 chunk:6299728
a3 chunk:6299776
p chunk_size value:49
p chunk size:48
free a1 mchunk_size value:49
free a2 fd value:6299680 //指向A1
free a3 fd value:6299728 //指向A2
四、常用malloc/free函数使用注意事项
- 后分配的内存先释放,因为ptmalloc收缩内存是从top chunk开始,如果与top chunk相邻的chunk不能释放,top chunk以下的chunk都无法释放。
- Ptmalloc不适合用于管理长生命周期的内存,特别是持续不定期分配和释放长生命周期的内存,这将导致ptmalloc内存暴增。
- 多线程分阶段执行的程序不适合用ptmalloc,这种程序的内存更适合用内存池管理
- 尽量减少程序的线程数量和避免频繁分配/释放内存。频繁分配,会导致锁的竞争,最终导致非主分配区增加,内存碎片增高,并且性能降低。
- 防止内存泄露,ptmalloc对内存泄露是相当敏感的,根据它的内存收缩机制,如果与top chunk相邻的那个chunk没有回收,将导致top chunk一下很多的空闲内存都无法返回给操作系统。
- 防止程序分配过多内存,或是由于Glibc内存暴增,导致系统内存耗尽,程序因OOM被系统杀掉。预估程序可以使用的最大物理内存大小,配置系统的/proc/sys/vm/overcommit_memory,/proc/sys/vm/overcommit_ratio,以及使用ulimt –v限制程序能使用虚拟内存空间大小,防止程序因OOM被杀掉。
相关文章:

ptmalloc源码分析 - malloc/free函数的实战篇(12)
目录 一、chunk的大小实验 二、获取使用中的chunk信息的实验 三、小内存块尝试获取fd信息的实验 四、常用malloc/free函数使用注意事项 看了前面11章节的内容,我们也基本了解了ptmalloc的内存管理逻辑。此处也可以通过一些手段,获取到chunk的信息&am…...
博弈论(奇偶考虑法)+计数+DP(判定转dp):CF838C
首先题目有博弈,先分析一波最优策略(步骤:分析性质)。 两个人,所以显然考虑奇偶考虑法递归考虑。 首先删就是使子问题-1,重新排列是在当前子问题里的。 一个串的排列是有限的,所以这里就可以…...

郁金香2021年游戏辅助技术中级班(一)
郁金香2021年游戏辅助技术中级班(一) 用代码读取utf8名字字节数组搜索UTF-8字符串 用CE和xdbg分析对象名字从LUA函数的角度进行分析复习怪物名字偏移 用CE和xdbg分析对象数组认识虚函数表分析对象数组 分析对象数组链表部分链表的定义链表的数据在内存里…...

加密货币交易所偿付能力的零知识证明
如何检测下一个 FTX 和 Mt. Gox 加密货币交易所 FTX 的内爆导致数十亿客户资金流失,这是加密货币历史上交易所破产的最新例子。历史可以追溯到 2014 年,当时处理 70% 比特币交易的历史最悠久、规模最大的交易所 Mt. Gox 丢失了用户的 850,000 个比特币。…...
软考网络工程师防火墙配置考点总结
(考试重点) 一、访问控制列表 管理网络当中的数据流量,实现数据过滤的重要手段。可以在路由器、三层交换、二层交换和防火墙上实现。 隐藏规则:当前面的规则都匹配不上,华为默认允许,思科默认拒绝。 分…...

【IDEA】idea恢复pom.xml文件显示灰色并带有删除线
通过idea打开spring boot项目后,发现每个服务中的pom.xml文件显示灰色并带有删除线,下面为解决方案 问题截图 解决方案 打开file——settings——build,execution,deployment——Ignored Files,把pom.xml前面的复选框去掉,去掉之…...
Python数据分析之Excel
Openpyxl库 1、Openpyxl模块2、Excel写入2.1、新建2.2、添加数据2.3、单元格格式 3、Excel读取4、Excel的CRUD4.1、查4.2、改4.3、删 1、Openpyxl模块 Openpyxl是一个用于处理xlsx格式Excel表格文件的第三方python库,几乎支持Excel表格的所有操作 基本概念&#x…...

NISP证书是什么?NISP含金量如何呢?
一、NISP是什么 NISP证书是国家信息安全水平考试(National Information Security Test Program,简称NISP),是由中国信息安全测评中心实施培养国家网络空间安全人才的项目。由国家网络空间安全人才培养基地运营/管理,并…...

操作系统备考学习 day6(2.3.2 - 2.3.4)
操作系统备考学习 day6 第二章 进程与线程2.3 同步与互斥2.3.2 实现临界区互斥的基本方法单标记法双标志先检查法双标志后检查法Peterson算法 进程互斥的硬件实现方法中断屏蔽方法TestAndSet指令Swap指令 2.3.3 互斥锁2.3.4 信号量整型信号量记录型信号量 第二章 进程与线程 2…...

家电行业 EDI:Miele EDI 需求分析
Miele是一家创立于1899年的德国公司,以其卓越的工程技术和不懈的创新精神而闻名于世。作为全球领先的家电制造商,Miele的经营范围覆盖了厨房、洗衣和清洁领域,致力于提供高品质、可持续和智能化的家电产品。公司的使命是为全球消费者创造更美…...
Android ConstraintLayout app:layout_constraintHorizontal_weight
Android ConstraintLayout app:layout_constraintHorizontal_weight <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:…...

FPGA行业应用一:LED控制器
什么是LED控制器 LED控制器已经有很多年头了,应该是上世纪90年代就开始有了。它的主要构成是: 1:视频信号源——如 电脑,机机,DVD,U盘等 2:视频处理器——通过 HDMI/DVI/网口接收来自视频源的…...
Pyspark读写csv,txt,json,xlsx,xml,avro等文件
1. Spark读写txt文件 读: df spark.read.text("/home/test/testTxt.txt").show() ------------- | value| ------------- | a,b,c,d| |123,345,789,5| |34,45,90,9878| -------------2. Spark读写csv文件 读: # 文件在hdfs上…...

LeetCode 接雨水 双指针
原题链接: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题面: 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:…...

【Linux】【网络】传输层协议:UDP
文章目录 UDP 协议1. 面向数据报2. UDP 协议端格式3. UDP 的封装和解包4. UDP 的缓冲区 UDP 协议 UDP传输的过程类似于寄信。 无连接:知道对端的IP和端口号就直接进行传输,不需要建立连接。不可靠:没有确认机制,没有重传机制&am…...

数字音频工作站FL Studio 21中文版下载及电音编曲要用乐理吗 电音编曲步骤
FL Studio 21是一款强大的数字音频工作站(DAW)软件,为您提供一个完整的软件音乐制作环境。它是制作高质量的音乐、乐器、录音等的完整解决方案。该程序配备了各种工具和插件,帮助你创建专业的虚拟乐器,如贝斯、吉他、钢…...

金蝶云星空与旺店通·企业奇门对接集成其他出库查询打通创建其他出库单
金蝶云星空与旺店通企业奇门对接集成其他出库查询打通创建其他出库单 源系统:金蝶云星空 金蝶K/3Cloud(金蝶云星空)是移动互联网时代的新型ERP,是基于WEB2.0与云技术的新时代企业管理服务平台。金蝶K/3Cloud围绕着“生态、人人、体验”&#…...

Visual Studio 如何删除多余的空行,仅保留一行空行
1.CtrlH 打开替换窗口(注意选择合适的查找范围) VS2010: VS2017、VS2022: 2.复制下面正则表达式到上面的选择窗口: VS2010: ^(\s*)$\n\n VS2017: ^(\s*)$\n\n VS2022:^(\s*)$\n 3.下面的替换窗口皆写入 \n VS2010: \n VS2017: \n VS2022: \n …...

java spring cloud 企业电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展
功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查看所…...

112. 路径总和
力扣题目链接(opens new window) 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树,以及目标和 sum 22…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...