公司网站建设项目的成本计划,广东省建设行业数据开放平台,桐乡住房和建设局网站,一个网站如何赚钱文章目录1 进程内存分配探究1.1 代码1.2 试验过程2 线程内存分配探究2.1 代码2.2 试验过程3 总结参考资料#xff1a;1.
嵌入式软件开发杂谈#xff08;3#xff09;#xff1a;Linux下内存与虚拟内存2.
嵌入式软件开发杂谈#xff08;1#xff09;#xff1a;Linux下最…
文章目录1 进程内存分配探究1.1 代码1.2 试验过程2 线程内存分配探究2.1 代码2.2 试验过程3 总结参考资料1.
嵌入式软件开发杂谈3Linux下内存与虚拟内存2.
嵌入式软件开发杂谈1Linux下最大能创建多少线程在链接1中我们可以了解到系统为每一个进程分配了4GB的虚拟内存空间其中3GB为用户空间是每个进程独有的1GB为内核空间所有的进程以及内核共同享有。
在链接2中我们了解到系统为每个线程分配独立的堆栈不同的系统有不同的大小在32位linux系统上默认为8MB。
在上篇文章中介绍了系统以及进程相关的内存指标但是有个疑问当进程运行时候系统是如何来分配内存的是直接分配3GB给到内存还是按需分配最大3GB通过下面代码来探究一番。
PS:下面测试环境为Ubuntu 64位系统。
1 进程内存分配探究
1.1 代码
#include stdio.h
#include stdlib.hint 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 stdio.h
#include stdlib.h
#include unistd.h
#include pthread.h
#include sys/prctl.hvoid *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的内存而不是我们真正需要的内存
后面章节将解决这几个问题。