【UNIX】内核对内核空间内存的管理以及对用户进程的堆内存分布

常用的内核内存分配函数

1)_get_free_pages是最原始的内存分配方式,至二级从伙伴系统中获取原始页框,返回值为第一个页框的起始地址。_get_free_pages在实现上只是封装了alloc_pages函数,而alloc_pages分配的长度为1<

2)Kmem_cache_alloc是基于slab分配器的一种内存分配方式,适用于反复分配释放同一大小内存的场合。首先用Kmem_cache_alloc从该高速缓存区域中获取新的内存块。在2.6内核中一次最多能申请1<< 5*4KB也就是128KB连续物理内存

3)Kmalloc是内核中常见的一种内存分配方式,他们通过调用kmem_cache_alloc函数实现,kmalloc一次最多申请128KB连续的物理内存,如果大于128KB则编译不通过

4)Vmalloc 前面几种分配方式都是物理连续的,能保证较低的平均访问时间。但是在某些场合,对内存区的请求不是很频繁,较高的内存访问也可以接受,这就可以分配一段线性连续,物理不连续的地址,带来的好处就是可以分配较大的内存,对于vmalloc分配的内存空间大小一般没有限制,但是一般内存大小最好不要大于1GB

5)Dma_alloc_coherent ,DMA是一种硬件机制,允许外围设备和主存之间直接传输io数据,而不需要CPU的参与,使用DMA机制能大幅度提高与设备的通信的吞吐量

6)Ioremap

Void *ioremap(unsigned long offset ,unsigned long size )

Ioremap是一种更直接的内存分配方式,使用时直接指定物理起始地址和需要分配的内存大小,然后将该段物理地址映射到内核地址空间,Ioremap用到的物理地址事先是知道确定的,和上面的几种方式不同,并不是分配一段新的物理地址内存,ioremap多用于设备驱动,实现了物理地址和虚拟地址的相互转化,这种机制在Linux内核设备驱动中起着重要的作用。可以让CPU通过虚拟地址的访问间接的访问外部设备的io空间。

用户进程的堆内存的分布

extern void *malloc(unsigned int num_bytes);

Malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void*?类型。void* 表示未确定类型的指针。C规定,void* 类型可以强制转换为任何其它类型的指针。

功能:分配长度为num_bytes字节的内存块

返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。

从函数声明上可以看出。malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:

int *p;

p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);

或:

int* parr;

parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;

而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。

int* p;

p = (int *) malloc (sizeof(int)*128);//分配128个(可根据实际需要替换该数值)整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中

double *pd=(double *) malloc (sizeof(double)*12);//分配12个double型存储单元,并将首地址存储到指针变量pd中

分配机制

 malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。

时间: 2024-12-04 15:00:57

【UNIX】内核对内核空间内存的管理以及对用户进程的堆内存分布的相关文章

【转载】java项目中经常碰到的内存溢出问题: java.lang.OutOfMemoryError: PermGen space, 堆内存和非堆内存,写的很好,理解很方便

Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决 解决方案 在 catalina.bat 里的 蓝色代码前加入: 红色代码 rem ----- Execute The Requested Command --------------------------------------- set JAVA_OPTS=%JAVA_OPTS%-server -Xms800m -Xmx1

Linux下的进程类别(内核线程、轻量级进程和用户进程)以及其创建方式--Linux进程的管理与调度(四)

本文声明 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux-4.5 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度-之-进程的创建 本文中出现的,内核线程,轻量级进程,用户进程,用户线程等概念,如果不太熟悉, 可以参见 内核线程.轻量级进程.用户线程三种线程概念解惑(线程≠轻量级进程) Linux进程类别 虽然我们在区分Linux进程类别, 但是我还是想说Linux下只有一种类型的进程,那就是task_str

linux 内存地址空间管理 mm_struct

http://blog.csdn.net/yusiguyuan/article/details/39520933 Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起.(所依据的代码是2.6.32.60) 无论是内核线程还是用户进程,对于内核来说,无非都是task_struct这个数据结构的一个实例而已,task_struct被称为进程描述符(process descriptor),因为它记录了这个进程所有的context.其中有一个被称为'内存描述符'(mem

Linux堆内存管理深入分析

(上半部) 作者:走位@阿里聚安全 0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞利用两种.国内关于栈溢出的资料相对较多,这里就不累述了,但是关于堆溢出的漏洞利用资料就很少了.鄙人以为主要是堆溢出漏洞的门槛较高,需要先吃透相应操作系统的堆内存管理机制,而这部分内容一直是一个难点.因此本系列文章主要从Linux系统堆内存管理机制出发,逐步介绍诸如基本堆溢出漏洞.基于unlink的堆溢出漏洞利用.double fr

Linux堆内存管理深入分析(上)

Linux堆内存管理深入分析 (上半部) 作者:走位@阿里聚安全 ? 0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞利用两种.国内关于栈溢出的资料相对较多,这里就不累述了,但是关于堆溢出的漏洞利用资料就很少了.鄙人以为主要是堆溢出漏洞的门槛较高,需要先吃透相应操作系统的堆内存管理机制,而这部分内容一直是一个难点.因此本系列文章主要从Linux系统堆内存管理机制出发,逐步介绍诸如基本堆溢出漏洞.基于unlink的

Linux堆内存管理深入分析 (上半部)【转】

转自:http://www.cnblogs.com/alisecurity/p/5486458.html 0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞利用两种.国内关于栈溢出的资料相对较多,这里就不累述了,但是关于堆溢出的漏洞利用资料就很少了.鄙人以为主要是堆溢出漏洞的门槛较高,需要先吃透相应操作系统的堆内存管理机制,而这部分内容一直是一个难点.因此本系列文章主要从Linux系统堆内存管理机制出发,逐步介绍诸

JAVA内存管理之堆内存和栈内存

我们常常做的是将Java内存区域简单的划分为两种:堆内存和栈内存.这种划分比较粗粒度,这种划分是着眼于我们最关注的.与对象内存分配密切相关的两类内存域.其中栈内存指的是虚拟机栈,堆内存指的是java堆. 1.栈内存,即虚拟机栈.每个方法被执行的时候都会同时创建一个栈帧,用来存储局部变量,操作栈,动态链接,方法出口等信息.局部变量包括各种基本类型的变量和对象的引用变量都是在方法的栈内存中分配.其中,64位长度的long和double类型的数据占用2个局部变量的空间,其他数据类型只占用1个.局部变量

Spark1.5堆内存分配

这是spark1.5及以前堆内存分配图 下边对上图进行更近一步的标注,红线开始到结尾就是这部分的开始到结尾 spark 默认分配512MB JVM堆内存.出于安全考虑和避免内存溢出,Spark只允许我们使用堆内存的90%,这在spark的spark.storage.safetyFraction 参数中配置着.也许你听说的spark是一个内存工具,Spark允许你存储数据在内存.其实,Spark不是真正的内存工具,它只是允许你使用内存的LRU(最近最少使用)缓存 .所以,一部分内存要被用来缓存你要

Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解)

(进程的虚拟存储器映像布局详解) 前言:原文来自于http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/ 这里只是对其进行翻译,并且重构了原文中的图片.译注则是我增加的内容,用来解释原文或提出问题:由于个人水平有限,译文和译注中的错误之处还请广大坛友提出指正,不胜感激. 下面采用分段中英对照的方式列出内容: Memory management is the heart of operating systems; i