面试中几个基本的重要问题总结
2011-05-04 11:35
337 查看
1、堆和栈的区别,堆和栈的最大限制
堆主要用来分配动态内存,操作系统提供了malloc等内存分配机制来供程序员进行堆内存的分配,同时,堆内存的释放需要程序员来进行。malloc分配的是虚拟地址空间,和用到的实实在在的物理内存是两码事,只有真正往空间里写东西了,os内核会触发缺页异常,然后才真正得到物理内存。32位Linux系统总共有4G内存空间,Linux把最高的1G(0xCFFFFFFF-0xFFFFFFFF)作为内核空间,把低地址的3G(0x00000000-0xBFFFFFFF)作为用户空间。malloc函数在这3G的用户空间中分配内存,能分配到的大小不超过3G,需除去栈、数据段(初始化及未初始化的)、共享so及代码段等占的内存空间。堆的地址空间是由低向高增长的(先分配低地址)。我用以下程序进行测试:
发现最大能分配的内存约为2.147GB。
栈由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。栈的地址空间是由高向低减少的(先分配高地址)。在Linux中,用ulimit -a命令可以看到栈的最大分配空间(stack size)是8192kB,即8MB多。
2、Linux中进程最大地址空间
Linux的虚拟地址空间也为0~4G。Linux内核将虚拟的4G字节的空间分为两部分。
将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为"内核空间"。将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为"用户空间"。因为每个进程可以通过系统调用进入内核,因此,Linux内核由系统的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。
其中,很重要的一点是虚拟地址空间,并不是实际的地址空间。进程地址空间是用多少分配多少,4G仅仅是最大限额而已。往往,一个进程的地址空间总是小于4G的,你可以通过查看/proc/pid/maps文件来获悉某个具体进程的地址空间。但进程的地址空间并不对应实际的物理页,Linux采用Lazy的机制来分配实际的物理页("Demand paging"和"和写时复制(Copy On Write)的技术"),从而提高实际内存的使用率。即每个虚拟内存页并不一定对应于物理页。虚拟页和物理页的对应是通过映射的机制来实现的,即通过页表进行映射到实际的物理页。因为每个进程都有自己的页表,因此可以保证不同进程的相从上到下(地址从高到低)依次为栈(函数内部局部变量),堆(动态分配内存) ,bss段(存未初始化的全局变量),数据段(存初始化的全局变量),文本段(存代码)同虚拟地址可以映射到不同的物理页,从而为不同的进程都可以同时拥有4G的虚拟地址空间提供了可能。
3、C/C++程序在Linux中的内存布局
用以下程序进行测试
运行结果如下:
stack segment: i:0xbfccc1f8, j:0xbfccc1f4
heap segment: ip:0x97bd008
bss segment: pear:0x80497c0, peach:0x80497a8
data segment: mango:0x804978c, melon:0x8049790
由此可见:从上到下(地址从高到低)依次为栈(函数内部局部变量),动态链接库,堆(动态分配内存),bss段(存未初始化的全局变量),数据段(存初始化的全局变量),文本段(存代码)
4、C/C++程序从源程序到目标文件的生成过程
见http://blog.csdn.net/vividonly/archive/2011/05/06/6399530.aspx一文
堆主要用来分配动态内存,操作系统提供了malloc等内存分配机制来供程序员进行堆内存的分配,同时,堆内存的释放需要程序员来进行。malloc分配的是虚拟地址空间,和用到的实实在在的物理内存是两码事,只有真正往空间里写东西了,os内核会触发缺页异常,然后才真正得到物理内存。32位Linux系统总共有4G内存空间,Linux把最高的1G(0xCFFFFFFF-0xFFFFFFFF)作为内核空间,把低地址的3G(0x00000000-0xBFFFFFFF)作为用户空间。malloc函数在这3G的用户空间中分配内存,能分配到的大小不超过3G,需除去栈、数据段(初始化及未初始化的)、共享so及代码段等占的内存空间。堆的地址空间是由低向高增长的(先分配低地址)。我用以下程序进行测试:
#include <stdlib.h> #include <stdio.h> int main() { char *a = NULL; unsigned long size = 2147 * 1000000; a = (char *)malloc(size); if(a == NULL){ perror("malloc failed/n"); }else{ printf("malloc success/n"); } free(a); return 0; }
发现最大能分配的内存约为2.147GB。
栈由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。栈的地址空间是由高向低减少的(先分配高地址)。在Linux中,用ulimit -a命令可以看到栈的最大分配空间(stack size)是8192kB,即8MB多。
2、Linux中进程最大地址空间
Linux的虚拟地址空间也为0~4G。Linux内核将虚拟的4G字节的空间分为两部分。
将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为"内核空间"。将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为"用户空间"。因为每个进程可以通过系统调用进入内核,因此,Linux内核由系统的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。
其中,很重要的一点是虚拟地址空间,并不是实际的地址空间。进程地址空间是用多少分配多少,4G仅仅是最大限额而已。往往,一个进程的地址空间总是小于4G的,你可以通过查看/proc/pid/maps文件来获悉某个具体进程的地址空间。但进程的地址空间并不对应实际的物理页,Linux采用Lazy的机制来分配实际的物理页("Demand paging"和"和写时复制(Copy On Write)的技术"),从而提高实际内存的使用率。即每个虚拟内存页并不一定对应于物理页。虚拟页和物理页的对应是通过映射的机制来实现的,即通过页表进行映射到实际的物理页。因为每个进程都有自己的页表,因此可以保证不同进程的相从上到下(地址从高到低)依次为栈(函数内部局部变量),堆(动态分配内存) ,bss段(存未初始化的全局变量),数据段(存初始化的全局变量),文本段(存代码)同虚拟地址可以映射到不同的物理页,从而为不同的进程都可以同时拥有4G的虚拟地址空间提供了可能。
3、C/C++程序在Linux中的内存布局
用以下程序进行测试
#include <stdio.h> #include <stdlib.h> char pear[40]; static double peach; int mango = 13; static long melon = 2001; int main() { int i = 3, j, *ip; ip = malloc(sizeof(i)); pear[5] = i; peach = 2.0 * mango; printf("stack segment: i:%p, j:%p/n", &i, &j); printf("heap segment: ip:%p/n", ip); printf("bss segment: pear:%p, peach:%p/n", pear, &peach); printf("data segment: mango:%p, melon:%p/n", &mango, &melon); //printf("the stack top is near %p/n", &i); return 0; }
运行结果如下:
stack segment: i:0xbfccc1f8, j:0xbfccc1f4
heap segment: ip:0x97bd008
bss segment: pear:0x80497c0, peach:0x80497a8
data segment: mango:0x804978c, melon:0x8049790
由此可见:从上到下(地址从高到低)依次为栈(函数内部局部变量),动态链接库,堆(动态分配内存),bss段(存未初始化的全局变量),数据段(存初始化的全局变量),文本段(存代码)
4、C/C++程序从源程序到目标文件的生成过程
见http://blog.csdn.net/vividonly/archive/2011/05/06/6399530.aspx一文
相关文章推荐
- 面试中几个基本的重要问题总结
- 面试中几个基本的重要问题总结
- 面试中几个基本的重要问题总结
- 最近android面试问题总结,你会几个?
- MFC的几个基本问题总结
- 用友电话面试后的几个问题总结
- 用Quartus II + Verilog 做FPGA/CPLD设计/仿真的几个基本问题(自己总结的,对初学者有效)
- 总结我在几个大公司面试中遇到的问题
- MSN几个面试问题总结
- MSN几个面试问题总结
- 数据库事务总结 基本特征 并发问题 隔离级别(几个文章的综合,下面有链接)
- 最近在准备面试,总结了几个java中面向对象的几个问题,问题本事还不够全面,要想知道还是要自己去找,但是在面试上应该是没多大问题了
- JAVA面试中的几个重要基础问题
- 关于“foreach循环”中遇到的几个问题总结
- 25个最基本的JavaScript面试问题及答案
- WCF部署于IIS使用的几个问题总结
- 2016年校招秋招 C++开发 面试问题总结(中兴、CVTE、瑞晟、华为、YY)
- 最近面试的几个额外问题
- IBM几个电话面试问题
- 一次电话Java面试的问题总结(JDK8新特性、哈希冲突、HashMap原理、线程安全、Linux查询命令、Hadoop节点)