堆栈认知——堆简介

参考:Linux笔记–堆简介
地址:https://qingmu.blog.csdn.net/article/details/119510863

目录

  • 1、前言
  • 2、堆的由来
  • 3、Linux中堆简介
  • 4、堆分类
    • 4.1、请求堆
    • 4.2、释放堆
  • 5、内存分配背后的系统调用
  • 6、堆相关数据结构
  • 7、堆的申请
  • 8、调试验证

1、前言

当前针对各大平台主要有如下几种堆内存管理机制:

平台堆管理机制
dlmallocGeneral purpose allocator
ptmalloc2glibc
jemallocFreeBSD and Firefox
tcmallocGoogle
libumemSolaris

在本文中我们主要说的是Linux中glibc的堆管理机制。

2、堆的由来

  • Linux中早期的堆分配与回收由Doug Lea 实现。 但是它在并行处理多线程的时候,会共享进程的堆内存空间。因此,为了安全性,一个线程使用堆时,会进行加锁。

  • 然而,与此同时,加锁会导致其他线程无法使用堆,降低了内存分配和回收的高效性。同时,如果多线程使用时,没能正确控制,也有可能引起内存分配和回收的正确性。

  • Wolfram Gloger 在Doug Lea 的基础上进行改进使其支持多线程,这个堆分配器就是ptmalloc。在glibc-2.3.x.之后,glibc中集成了ptmalloc2。

1、只有当真正访问一个地址的时候,系统才会建立虚拟页面与物理页面的映射关系。2、所以虽然操作系统已经给程序分配了很大的一块内存,
但是这块内存其实只是虚拟内存。只有当用户使用到相应的内存时,
系统才会真正分配物理内存给用户使用。

3、Linux中堆简介

  • 目前Linux标准发行版中使用的堆分配器是glibc中的堆分配器:ptmalloc2。ptmalloc2主要是通过malloc/free函数来分配和释放内存块。

  • 需要注意的是, 在内存的分配与使用过程中,Linux有这样的一个基本内存管理思想:

4、堆分类

4.1、请求堆

相应用户的申请内存请求,向操作系统申请内存,然后将其返回给用户程序。同时,为了保持内存管理的高效性,内存一般都会预先分配一块很大的连续的内存(这块很大的内存称之为top_chunk),然后让堆管理器通过某种算法管理这块内存。只有当出现堆空间不足的情况,堆管理器才会再次与操作系统交互。

通俗的说就是我们的malloc或者new等申请内存的操作函数。

4.2、释放堆

管理用户所释放的内存。一般来说,用户释放的内存并不是直接返还给操作系统的,而是由堆管理器进行管理。这些释放的内存可以来响应用户新申请的内存的请求。
通俗的说就是我们的free或者delete等释放内存的操作函数。

5、内存分配背后的系统调用

  • 我们在申请与释放内存的函数中,无论是malloc还是free函数,一般都会经常的使用,但是他们并不是真正与系统交互的函数。

  • 这些函数背后的系统调用主要是(s)brk函数以及mmap,unmmap函数。

具体流程如下图所示:
在这里插入图片描述

  • 对于堆的操作,操作系统提供了brk函数,我们可以通过增加brk的大小来向操作系统申请内存。

  • 初始时,堆得起始地址start_brk以及堆的当前末尾brk指向的地址。根据是否开启ALSR(地址随机化)保护时,两者的具体位置会有所不同。

  • 不开启ALSR保护时,start_brk以及brk会指向data/bss段的结尾。

  • 开启ALSR保护时,start_brk以及brk也会指向同一位置,只是这个位置是在data/bss段的结尾后的随机偏移处。

可参考下图:
在这里插入图片描述

6、堆相关数据结构

堆的操作是十分的复杂的,那么在glibc内部必然也有精心设计的数据结构(链表)来管理它,与堆相应的数据结构主要分为:

宏观结构:1、包含堆的宏观信息,可以通过这些数据结构索引堆的基本信息2、主要是堆块之间的链接微观结构:1、用于处理堆分配与回收的内存块2、主要还是怎么处理堆的分配与回收中的内存块3、malloc & free

7、堆的申请

  • 在程序的执行中,我们由malloc申请的内存称之为chunk。这块内存在ptmalloc内部用malloc_chunk 结构体来表示。当程序申请的chunk被free后,会被加入到空闲管理列表中,这个列表被称之为binlist。

  • 无论一个chunk的大小如何,处于分配状态还是释放状态,他们都使用一个统一的结构体。

  • 虽然他们都使用同一个数据结构,但是根据是否被释放,他们的表现形式会不一样。

malloc_chunk 的具体形式如下:

struct malloc_chunk
{INTERNAL_SIZE_T  prev_size;INTERNAL_SIZE_T  size;struct malloc_chunk *fd;struct malloc_chunk *bk;struct malloc_chunk *fd_nextsize;struct malloc_chunk *bk_nextsize;
}

我们由malloc申请一块0x100的内存的时候,这块内存在ptmalloc内部用malloc_chunk来表示,但是他的大小并不是0x100的大小,还得加上我们操作不了的prev_size和size大小,一般为0x10。

参数详解:

size

1、他是一个标志位2、该字段的低三个比特对chunk的大小没有影响,他们从低到高分别表示NON_MAIN_ARENA,记录当前chunk是否不属于主线程,1表示不属于,0表示属于。3、IS_MAPPED ,记录当前chunk是否有mmap分配的。4、PREV_INUSE,记录前一个chunk块是否被分配。一般来说,堆中的第一个被分配的内存块的size字段的P位都会被置位1,以便于防止访问前面的非法内存。当一个chunk的size的P位为0时,我们能通过pre_size字段来获取上一个chunk的大小以及地址。这也方便进行空闲chunk之间的合并。A|M|P

fd,bk

1、chunk处于分配状态时,从fd字段开始是用户数据。chunk空闲时,会被添加到空闲的管理列表中(binlist),其字段的含义是指向下一个(非物理相邻)空闲的chunk。2、bk指向上一个(非物理相邻)空闲chunk3、通过fd和bk可以将空闲的chunk块加入到空闲的chunk块链表进行统一管理

fd_nextsize bk_nextsize

1、也是同样只有chunk空闲的时候才可以使用,不过其用于较大的chunk(large chunk)2、fd_nextsize指向前一个与当前chunk大小不用的第一个空闲块,不包含bin的头指针3、bk_nextsize指向后一个与当前chunk大小不用的第一个空闲块,包含bin的头指针4、一般空闲的large chunk 在fd的遍历顺序中按照由大到小顺序排列。这样可以避免在寻找合适chunk时挨个遍历

8、调试验证

我们使用gdb调试验证一下

调试的C代码如下:

#include<stdio.h>
#include<malloc.h>
#include<unistd.h>
#include<string.h>
int main(){int size = 0x100;void *p = malloc(size);void *junk = malloc(size);void *q = malloc(size);void *r = malloc(size);printf("p:0x%x\n",p);printf("q:0x%x\n",q);printf("r:0x%x\n",r);strcpy(p,"aaaaaaaabbbbbbbb");strcpy(q,"ccccccccdddddddd");strcpy(r,"eeeeeeeeffffffff");sleep(0);free(p);sleep(0);free(q);sleep(0);
//	q = malloc(0x600);
//	sleep(0);return 0;
}

在这里插入图片描述
可以看到在程序起来后并没有堆的任何信息,本来我们也没申请嘛,咱们接着往下调

让其走完一个malloc走完,看一看:
在这里插入图片描述
这里我们申请的是0x100的大小,真是大小却是273(0x111),因为加上了我们不可操作的prev_size和size的大小。

接着往下看,走完printf:
在这里插入图片描述
我们发现printf也会创建堆块,为了存放标准输入标准输出的,咱们接着往下走,到给p,q,r赋值之后:
在这里插入图片描述
堆中的fd和bk都赋值为了我们赋值的东西。

再接着我们free掉p,再看一下堆的情况:
在这里插入图片描述
他的fd和bk已经被改变了,其值为libc中的地址,我们在把q给free掉:
在这里插入图片描述
我们会发现q的bk已经指向了q这个堆块的地址了,而q这个堆的fd就变成了p这个堆的地址了,他们被ptmalloc组成了链表形成了bin链。

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

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

相关文章

如何为 Horizon View 配置 VMware VSAN?

原文&#xff1a;http://myvirtualcloud.net/?p5440注明&#xff1a;本文内容基于 VMwareVSAN beta 版本撰写&#xff0c;请访问http://www.vmware.com/products/virtual-san/获得有关正式版本的更新信息。我已经在前面的文章中讨论了VSAN 给 Horizon View 带来的益处&#xf…

配置vscode远程免密登入Linux服务器

视频教程&#xff1a;https://www.bilibili.com/video/BV1s64y167cM?vd_sourcecc0e43b449de7e8663ca1f89dd5fea7d 参考&#xff1a;配置vscode远程免密登入Linux服务器 地址&#xff1a;https://blog.csdn.net/weixin_54178481/article/details/123977675?spm1001.2014.3001.…

Wss 3.0安装指南(一)

Wss 3.0安装指南(一) "基本" 模式 WSS3.0的安装可分为独立服务器安装和服务器场安装,前者是将所有的服务和应用安装在一台Server 上,后者则是…

智能五子棋基本思路

前些天闲时写的,在学数据结构的时拿来练手的.没技术含量,最有技术含量的AI部分,我是看别人(园子里叫二十四生的)的算法改的.刚弄了一下午小程序弄不过去,头疼,现无聊的紧,闲着发着玩.当消遣主要发下AI核心算法.有兴趣的同学用VB,VC.VC#都可以一起做着玩.保持对编程的兴趣.其它没…

webpack 4.0 配置文件 webpack.config.js文件的放置位置

一般webpack.config.js是默认放在根目录的&#xff0c;不在根目录的时候需要在package.json中制定位置&#xff0c;我的配置文件目录是config/webpack.config.js,在package.json文件中的配置为&#xff1a; "scripts": { "build": "webpack --mode p…

PowerShell远程管理Windows Server(2):公网访问【web形式】

*此文章只适合于windows server 2012版本以上&#xff1b;Powershell Web Access需要两个步骤才能使用&#xff1a;一、安装powershell web access功能&#xff1b;二、配置powershell web access&#xff1b;只要在服务器上启用powershell web access功能&#xff0c;即可通过…

POJ 3090 Visible Lattice Points 【欧拉函数】

<题目链接> 题目大意&#xff1a; 给出范围为(0, 0)到(n, n)的整点&#xff0c;你站在(0,0)处&#xff0c;问能够看见几个点。 解题分析&#xff1a;很明显&#xff0c;因为 N (1 ≤ N ≤ 1000) &#xff0c;所以无论 N 为多大&#xff0c;(0,1),(1,1),(1,0)这三个点一定…

精选 5 个漂亮的 CSS3 图片滑过特效

这篇文章将为大家分享5款漂亮的CSS3图片滑过特效&#xff0c;比如滑过后显示图片的详细文字介绍&#xff0c;又比如滑过后对图片进行淡入淡出的效果等等。让我们一起来看看&#xff0c;喜欢的朋友赶紧收藏。 1、非常酷的CSS3图片说明效果 在线演示 / 源码下载 2、纯CSS3图片相…

Cocos2d-x 3.0新引擎文件夹结构

Cocos2d-x 3.0新引擎文件夹结构2014年4月29日 Cocos2d-x 3.0学习作为一个Cocos2d-x的菜鸟&#xff0c;我倒是挺愿意关注不同版本号之间的差别&#xff0c;Cocos2d-x 3.0自2013年7月份開始公布alpha0-pre版本号&#xff0c;到2014年4月23日公布正式版&#xff0c;历经9个版本号…

SOA系列文章(二):服务设计原理:服务模式和反模式

服务设计系列的法则已经发展到最佳通信实践和取样相关编码的程度。本文提供了设计和实现网络服务的基本原理&#xff0c;并且对面向服务的体系结构(SOA)的相关概念做了一个简要的回顾&#xff0c;以及有关于几种模式和反模式的详细讨论&#xff0c;当构建网络服务时&#xff0c…

iOS程序启动原理(上)

为什么80%的码农都做不了架构师&#xff1f;>>> iOS程序启动原理 Info.plist 常见设置 建立一个工程后,会在Supporting files文件夹下看到一个"工程名-Info.plist"的文件,该文件对工程做一些运行期的配置,非常重要,不能删除. 在旧版Xcode创建的工程中,这…

何时使用委托而不使用接口

委托和接口都允许类设计器分离类型声明和实现。给定的接口可由任何类或结构继承和实现&#xff1b;可以为任何类中的方法创建委托&#xff0c;前提是该方法符合委托的方法签名。接口引用或委托可由不了解实现该接口或委托方法的类的对象使用。既然存在这些相似性&#xff0c;那…

microsoft project 出现不能保存为xls文件时可以按照如下方法解决

工具-》选项-》安全性转载于:https://www.cnblogs.com/oymx/p/3753291.html

多功能节点连线绘图控件Nevron Diagram for .NET使用方法及下载地址

Nevron Diagram for .NET是一个功能强大,世界上顶级的.NET图表控件.可扩展的图形报表构架&#xff0c;可以帮您创建功能丰富的Winforms及Webforms图表解决方案。这个产品构建于Nevron表述层框架之上&#xff0c;能为您提供令人激动的视觉冲击&#xff0c;您无法通过其它产品体验…

《DirectX 9.0 3D游戏开发编程基础》 第二章 绘制流水线 读书笔记

模型的表示 场景&#xff1a;物品或模型的集合 任何物品都可以用三角形网络逼近表示。我们经常用以下术语描述三角形网络&#xff1a;多边形(polygons)、图元(primitives)、网络几何单元(mesh geometry)。 描述三角形&#xff1a;指定三个顶点 描述物品&#xff1a;三角形单元列…

CocosCreator2.1.0渲染流程与shader

CocosCreator2.1.0版本正式支持导入3D模型 对于2.5D游戏的开发来说有着重要意义 自己此前在写捕鱼游戏时了解过自定义shader 并实现了4种不同的水波效果 但经过CocosCreator版本的不断升级 尤其是1.10和2.0两个版本 旧的渲染器被抛弃了 因此老的shader特效也全都不能用了 直到最…

Java开发人员的十大戒律

对Java开发者来说&#xff0c;有许多的标准和最佳实践。本文列举了每一个开发人员必须遵从的十大基本法则&#xff1b;如果有了可以遵从的规则而不遵从&#xff0c;那么将导致的是十分悲惨的结局。1&#xff0e; 在你的代码里加入注释每个人都知道这点&#xff0c;但不知何故…

c++学习书籍推荐《Advanced C++》下载

百度云及其他网盘下载地址&#xff1a;点我 作者简介 James Coplien先在威斯康星大学获得电气与计算机工程学士学位&#xff0c;后又在该大学获得计算机科学硕士学位。他在贝尔实验室的软件产品研发部门工作&#xff0c;在这个部门从一开始就使用C程序设计语言。近年来致力于大…

MySQL入门-3:安装与客户端工具

大纲1、安装 MySQL2、检索数据3、数据过滤一、安装环境CentOS-6.5-i386mysql 5.1.73为了方便&#xff0c;这里采用yum方式安装&#xff0c;对于学习实验环境完全没问题&#xff0c;注意下面的操作都以root身份操作。除非对MySQL需要定制化或者安装多个实例&#xff0c;建议使用…

实验吧-web-天下武功唯快不破(Python中byte和str的转换)

题目&#xff1a;看看响应头 打开网站&#xff0c;既然已经提示我们看响应头了&#xff0c;那我们就看看呗(习惯bp&#xff0c;也可直接F12查看) 可以看到&#xff0c;响应头部分有个FLAG&#xff0c;而且有提示&#xff1a;please post what you find with parameter:key 所以…