Linux性能学习(2.2):内存_进程线程内存分配机制探究
创始人
2024-05-28 22:09:41
0

文章目录

  • 1 进程内存分配探究
    • 1.1 代码
    • 1.2 试验过程
  • 2 线程内存分配探究
    • 2.1 代码
    • 2.2 试验过程
  • 3 总结

参考资料:
1. 嵌入式软件开发杂谈(3):Linux下内存与虚拟内存
2. 嵌入式软件开发杂谈(1):Linux下最大能创建多少线程?

在链接1中,我们可以了解到系统为每一个进程分配了4GB的虚拟内存空间,其中3GB为用户空间,是每个进程独有的,1GB为内核空间,所有的进程以及内核共同享有。

在链接2中,我们了解到系统为每个线程分配独立的堆栈,不同的系统有不同的大小,在32位linux系统上默认为8MB。

在上篇文章中介绍了系统以及进程相关的内存指标,但是有个疑问,当进程运行时候,系统是如何来分配内存的,是直接分配3GB给到内存,还是按需分配,最大3GB,通过下面代码来探究一番。

PS:下面测试环境为Ubuntu 64位系统。

1 进程内存分配探究

1.1 代码

#include 
#include int main()
{int ch = 0;int s32Size = 1024;char* s8Ptr = NULL;int s32Cnt = 0;while ((ch = getchar()) != EOF){printf("get char,malloc %d mem\n", s32Size);s8Ptr = NULL;s8Ptr = (char*)malloc(s32Size);if (NULL == s8Ptr){printf("malloc err\n");}else{printf("malloc success, cnt:%d, addr:%p\n", ++s32Cnt, s8Ptr);}}return 0;
}

上面代码,每当我们在终端输入一个字符,程序就申请1KB的内存,并且打印申请内存的地址。

1.2 试验过程

我们知道,堆是负责动态内存的分配,因此可以通过 # cat /proc/$(pid)/maps | grep heap
来查看进程的内存分配情况。

运行程序,然后使用top查看虚拟内存的使用情况以及使用上面指令来查看堆的使用情况。
在这里插入图片描述

# cat /proc/11031/maps | grep heap
00ae2000-00b03000 rw-p 00000000 00:00 0 

从上面可以可以看到这个进程的虚拟内存使用量为4352KiB,堆的地址为00ae2000-00b03000,换算一下堆的大小为132KB。但是此时程序并没有申请内存,怎么回事?

我们第一次申请内存,打印如下:

get char,malloc 1024 mem
malloc success, cnt:1, addr:0xae2830

然后查看虚拟内存VIRT使用量,还是4352KiB,并没有增加,堆的使用地址还是00ae2000-00b03000,也没有改变。

继续申请内存:

get char,malloc 1024 mem
malloc success, cnt:2, addr:0xae2c40
get char,malloc 1024 mem
malloc success, cnt:3, addr:0xae3050

第二次和第三次申请内存,VIRT和堆的信息仍然维持原状,没有改变,继续申请:

get char,malloc 1024 mem
malloc success, cnt:128, addr:0xb02c20

直到第128次申请内存时候,VIRT的使用量为4484KiB,比4352增加了132KB,而堆的使用量为264KB,比上次增加了132KB,信息如下:
在这里插入图片描述

cat /proc/11031/maps | grep heap
00ae2000-00b24000 rw-p 00000000 00:00 0                                  [heap]

继续申请内存,直到第258次申请内存,VIRT变为4616K,比4484增加了132KB,而堆的使用量为396KB,比上次增加了132KB,信息如下:

get char,malloc 1024 mem
malloc success, cnt:258, addr:0xb23c40

在这里插入图片描述

# cat /proc/11031/maps | grep heap
00ae2000-00b45000 rw-p 00000000 00:00 0                                  [heap]

从上面的测试中,我们看到第二次申请内存的地址为0xae2c40,而第一次申请内存的地址为0xae2830,两者相减,为1040,但是我们只申请了1024个字节,为什么会多16个字节?
第一个问题:为什么系统分配的内存比实际申请的内存大16个字节?

然后,我们可以看到,当程序运行时候,系统已经先为程序分配了132KB的内存,在随后我们申请内存时候,一直使用的是系统预先申请的132KB内存,直到我们申请的内存超过132KB,然后系统再次申请132KB,而不是我们需要多少就申请多少?
第二个问题:为什么系统会给进程申请132KB的内存,而不是我们真正需要的内存?

2 线程内存分配探究

2.1 代码

#include 
#include 
#include 
#include 
#include void *fun(void *arg)
{printf("----->thread_test\n");prctl(PR_SET_NAME, "thread_test");int ch = 0;int s32Size = 1024;char* s8Ptr = NULL;int s32Cnt = 0;while ((ch = getchar()) != EOF){printf("get char,malloc %d mem\n", s32Size);s8Ptr = NULL;s8Ptr = (char*)malloc(s32Size);if (NULL == s8Ptr){printf("malloc err\n");}else{printf("malloc success, cnt:%d, addr:%p\n", ++s32Cnt, s8Ptr);}}
}int main()
{int s32Ret = 0;pthread_t thread;if (getchar() != EOF){s32Ret = pthread_create(&thread, NULL, fun, NULL);		printf("pthread_create, ret:%d\n", s32Ret);}while(1) sleep(10);return 0;
}

上面代码,当我们第一次输入一个字符,则创建线程,随后再次输入字符则是分配内存

2.2 试验过程

运行程序,查看VIRT为6520KB,如下:
在这里插入图片描述

maps信息如下:
在这里插入图片描述

然后我们创建线程,查看VIRT和maps信息如下:
在这里插入图片描述
在这里插入图片描述

可以看到,VIRT由6520增加到14716,即增加了8MB,这个8MB是系统为每个线程创建时分配的。
然后开始第一次分配内存,VIRT和maps信息如下:
在这里插入图片描述
在这里插入图片描述

可以看到,当我们第一次申请内存的时候,VIRT由14716增加到80252,即系统为线程申请了64MB内存,而不是给进程分配的132KB内存。
第三个问题:为什么系统会给线程申请64MB的内存,而不是我们真正需要的内存?

开始第二次申请内存,VIRT和maps数据均没有变化,和进程中的分配机制一样,先从已经分配的内存中使用,当超过已经分配的内存时,才会重新分配新的内存。

get char,malloc 1024 mem
malloc success, cnt:1, addr:0x7f9bac0008c0get char,malloc 1024 mem
malloc success, cnt:2, addr:0x7f9bac000cd0

上面是程序的打印信息,可以看到我们申请了1024字节的内存,但是系统还是分配了1040个字节的内存,即多分配了16字节的内存,和问题1一致。

3 总结

通过上面的测试,我们得出了三个问题:

  • 第一个问题:64位系统,为什么系统分配的内存比实际申请的内存大16个字节?
  • 第二个问题:64位系统,为什么系统会给进程申请132KB的内存,而不是我们真正需要的内存?
  • 第三个问题:64位系统,为什么系统会给线程申请64MB的内存,而不是我们真正需要的内存?

后面章节将解决这几个问题。

相关内容

热门资讯

邂逅新老朋友 转自:经济日报“欢迎来到英国馆。”在第五届中国国际消费品博览会现场,英国驻华大使馆代表、英国馆馆长沈...
#五一错峰机票直降四成# 这个... #五一错峰机票直降四成# 这个五一,文旅消费彻底燃爆!携程数据显示:县域游、乡村游订单增长超20%,...
王化:小米 YU7 汽车“下次... IT之家 5 月 3 日消息,小米集团公关部总经理 @王化今天转发 @小米汽车的上海车展总结博文,并...
维生素C是西梅的16倍,还高钙... 转自:中国科协有一种野菜,经常在乡间田野、路旁沟边出现,以前人们会拿它喂给猪吃,因而它曾被当作“猪食...
财政部印发办法规范会计奖惩信息... 转自:新华社为贯彻落实《中华人民共和国会计法》有关规定,做好会计奖惩信息记录归集,财政部近日印发了《...
幼儿园园长之子性侵猥亵女童有超... 转自:今晚报 #幼儿园园长之子性侵猥亵女童#【幼儿园#园...
即将影响福建!又要大反转!还有... 最新预报雨雨雨+强对流要来了!台风也有最新消息据福建气象最新发布——今天好天气继续陪伴我们的假日好时...
5月3日全国铁路预计发送旅客1... 转自:中工网工人日报-中工网记者 刘静记者从中国国家铁路集团有限公司(下称“国铁集团”)获悉,5月3...
虚拟电厂电力交易业务加速中 来源:@经济观察报微博记者 潘俊田“136号文出来之后,很多新能源电站都主动来找我们这类企业(虚拟电...
“补气血”是有顺序的,男女各有... 本文转自【人民日报】由于经常熬夜、缺乏运动、饮食不规律等原因,现代人容易出现腰膝酸软、皮肤暗沉、疲惫...
暂停售票!湖北多个景区紧急提醒 转自:荆门发布今天(5月3日)“五一”假期进入第三天湖北多地景区火到限流截至上午11时恩施、宜昌等地...
一季度我国软件业务收入3147... 2025年一季度,我国软件和信息技术服务业(以下简称“软件业”)运行态势良好,软件业务收入稳健增长,...
中华全国体育基金会-香港赛马会... 5月2日,中华全国体育基金会-香港赛马会助力劳动者杯中国职工网球团体赛在北京市网球运动管理中心开幕。...
专家田间 “把脉”,智慧 “解... 转自:微讯江苏进入5月,气温节节攀升。气象数据显示,刚过去的4月,全国平均气温12.95℃,为196...
假期后三天暴雨、大暴雨来袭!出... 转自:中华人民共和国应急管理部“五一”假期后三天(5月3日至5日),南方降雨将再度发展增多,江南、华...
京剧姑娘拒绝为赚钱破坏传统 点... 转自:环球时报 【#京剧姑娘拒绝为赚钱破坏传统# 点赞!...
五一假期:贵州“村超”迎来中外... 5月2日,贵州榕江“村超”赛场迎来一场中外足球友谊赛。由贵州省黔东南苗族侗族自治州三穗鸭美食足球队与...
昆明2025年计划改造405个... 近日,昆明市2025年城镇老旧小区改造计划正式下达。今年共有盘龙区、官渡区、西山区、东川区、安宁市和...
时政微观察丨科学谋划“十五五”... 来源:央视新闻客户端“十四五”规划收官之年,如何科学谋划好“十五五”时期经济社会发展?一场谋篇布局的...
浙商证券:预计资金面月初重回均...   覃汉研究笔记  CORE IDEA  核心观点  资金面部分,未来一周,资金利率预计季节性回落,...