一个程序内存分配:
下图是APUE中的一个典型C内存空间分布图(虚拟内存)
例如:
int g1=0, g2=0, g3=0
int max(int i)
{
int m1=0,m2,m3=0, p_max
static n1_max=0,n2_max,n3_max=0
p_max = (int )malloc(10)
printf("打印max程序地址\n")
printf("in max: 0xx\n\n",max)
printf("打印max传入参数地址\n")
printf("in max: 0xx\n\n",&i)
printf("打印max函数中静态变量地址\n")
printf("0xx\n",&n1_max)//打印各本地变量的内存地址
printf("0xx\n",&n2_max)
printf("0xx\n\n",&n3_max)
printf("打印max函数中局部变量地址\n")
printf("0xx\n",&m1)//打印各本地变量的内存地址
printf("0xx\n",&m2)
printf("0xx\n\n",&m3)
printf("打印max函数中malloc分配地址\n")
printf("0xx\n\n",p_max)//打印各本地变量的内存地址
if(i) return 1
else return 0
}
int main(int argc, char **argv)
{
static int s1=0, s2, s3=0
int v1=0, v2, v3=0
int p
p = (int )malloc(10)
printf("打印各全局变量(已初始化)的内存地址\n")
printf("0xx\n",&g1)//打印各全局变量的内存地址
printf("0xx\n",&g2)
printf("0xx\n\n",&g3)
printf("======================\n")
printf("打印程序初始程序main地址\n")
printf("main: 0xx\n\n", main)
printf("打印主参地址\n")
printf("argv: 0xx\n\n",argv)
printf("打印各静态变量的内存地址\n")
printf("0xx\n",&s1)//打印各静态变量的内存地址
printf("0xx\n",&s2)
printf("0xx\n\n",&s3)
printf("打印各局部变量的内存地址\n")
printf("0xx\n",&v1)//打印各本地变量的内存地址
printf("0xx\n",&v2)
printf("0xx\n\n",&v3)
printf("打印malloc分配的堆地址\n")
printf("malloc: 0xx\n\n",p)
printf("======================\n")
max(v1)
printf("======================\n")
printf("打印子函数起始地址\n")
printf("max: 0xx\n\n",max)
return 0
}
打印结果:
ELF目标文件格式的最前端是 ELF****文件头(****ELF Header****) ,
包含了描述整个文件的基本属性,如ELF版本、目标机器型号、 程序入口地址 等
3 加载:
问题一:堆和栈的区别是啥? 一、预备知识D程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)D 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 *** 作方式类似于数据结构中的栈。
2、堆区(heap) D 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)D,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区 D常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区D存放函数体的二进制代码。
二、例子程序
这是一个前辈写的,非常详细
main.cpp
int a = 0全局初始化区
char *p1全局未初始化区
main()
{
int b栈
char s[] = abc栈
char *p2栈
char *p3 = 123456123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10)
p2 = (char *)malloc(20)
分配得来得10和20字节的区域就在堆区。
strcpy(p1, 123456)123456\0放在常量区,编译器可能会将它与p3所指向的123456优化成一个地方。
}
二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10)
在C++中用new运算符
如p2 = (char *)malloc(10)
但是注意p1、p2本身是在栈中的。
2.2
申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道 *** 作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址......>>
问题二:栈和堆具体的区别 数据存储和读取特征区别
堆,队列优先,先进先出(FIFO―first in first out)
栈,先进后出(FILO―First-In/Last-Out)。
堆和栈的区别与编程语言无关,硬件自身不同的数据存储方式有关。不同语言存储在堆和栈的数据类型也不一定相同。
1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据在多个线程或者多个栈之间是不可以共享的,但是在栈内部多个值相等的变量是可以指向一个地址的,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
3.Java中的数据类型有两种。
一种是基本类型(primitivetypes), 共有8种,即int,short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a= 3long b = 255L的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a= 3这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。
问题三:java 中 的 堆 和 栈 有 什 么 区 别 ? 要 详 细 点 的 ! java中堆(heap)和堆栈(stack)有什么区别 stack 和 heep 都是内存的一部分
stack 空间小,速度比较快, 用来放对象的引用
heep 大,一般所有创建的对象都放在这里。
栈(stack):是一个先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量.
在java中,所有基本类型和引用类型都在栈中存储.栈中数据的生存空间一般在当前scopes内(就是由{...}括起来的区域).
堆(heap):是一个可动态申请的内存空间(其记录空闲内存空间的链表由 *** 作系统维护),C中的malloc语句所产生的内存空间就在堆中.
在java中,所有使用new xxx()构造出来的对象都在堆中存储,当垃圾回收器检测到某对象未被引用,则自动销毁该对象.所以,理论上说java中对象的生存空间是没有限制的,只要有引用类型指向它,则它就可以在任意地方被使用.
1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
3. Java中的数据类型有两种。
一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。 这种类型的定义是通过诸如int a = 3long b = 255L的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。
另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。
这样,就出现了a与b同时均指向3的情况。特别注意的是,这种字面值的引用与类对象的引用不同。
假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。
相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。 如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的......>>
问题四:堆和栈的区别是什么 堆和栈的区别:
一、堆栈空间分配区别:
1、栈( *** 作系统):由 *** 作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其 *** 作方式类似于数据结构中的栈;
2、堆( *** 作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
二、堆栈缓存方式区别:
1、栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;
2、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
三、堆栈数据结构区别:
堆(数据结构):堆可以被看成是一棵树,如:堆排序;
栈(数据结构):一种先进后出的数据结构。
问题五:简述堆和栈的区别和联系 堆和栈的要点:
堆,队列优先,先进先出(FIFO―first in first out)。
栈,先进后出(FILO―First-In/Last-Out)。
一般情况下,如果有人把堆栈合起来说,那它的意思是栈,可不是堆。
堆和栈的对比分析:
1、堆栈空间分配
栈( *** 作系统):由 *** 作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其 *** 作方式类似于数据结构中的栈。
堆( *** 作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表
2、堆栈缓存方式
栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放。
堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
3、堆栈数据结构区别
堆(数据结构):堆可以被看成是一棵树,如:堆排序。
栈(数据结构):一种先进后出的数据结构。
问题六:java中堆和栈的区别 Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等 指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时 动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类 型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。
这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。
String是一个特殊的包装类数据。可以用:
String str = new String(abc)
String str = abc
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放abc,如果没有,则将abc存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。
比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。
String str1 = abc
String str2 = abc
System.out.println(str1==str2)true
可以看出str1和str2是指向同一个对象的。
String str1 =new String (abc)
String str2 =new String (abc)
System.out.println(str1==str2)false
用new的方式是生成不同的对象。每一次生成一个。
因此用第一种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的......>>
问题七:数据结构里堆和栈的区别 5分 简单的说 就是堆是无序的,你可以任意取任意插入 *** 作,而栈对任意元素的 *** 作都是有秩序的有约束的,
这个就是区别
根本上讲读取和写入的规则不同
至于怎罚存放的形态如何是不需要考虑的
问题八:堆和栈的区别 堆和栈
栈:由编译器自动分配并且释放,一般存储函数的参数局部变量等
堆:由程序员分配释放,若程不释放则系统释放
区别一:申请内存方式
栈:由系统自动分配,如变量的声明的同时会开辟空间,(int a; 开辟4个字节的空间)(静态指定)
堆:由程序员申请,需要制定大小(动态分配)
区别2:系统响应的不同
栈:只要剩余空间大于申请内存,系统就会提供,否则会栈溢出
堆:便历空闲地址链表,找到符合要求的,就删除该地址分配给程序,内梗的首地址记录分配的大小,(方便delete)多余的内存回收
区别3:空间大小不同
栈:连续的,编译时就确定的常数
堆:不连续,他的上限决定于系统中有效的虚拟内存
区别4:执行效率的不同
栈:由系统分配,速度快
堆:程序员分配,速度慢,容易产生内存碎片,不过用起来方便;
区别5:执行函数的不同
问题九:ios内存中的栈和堆的区别是什么?那些数据在栈上,在堆上 iOS中堆和栈的区别
管理方式:
对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来讲,释放工作有程序员控制,容易产生memory Leak。
申请大小:
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域。这句话的意思是栈顶上的地址和栈的最大容量是系统预先规定好的,在Windows下,栈的大小是2M(也有的说1M,总之是编译器确定的一个常数),如果申请的空间超过了栈的剩余空间时候,就overflow。因此,能获得栈的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大笑受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
碎片的问题:
对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存快从栈中d出。
分配方式:
堆都是动态分配的,没有静态分配的堆。栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配是有alloc函数进行分配的,但是栈的动态分配和堆是不同的,他的动态分配由编译器进行释放,无需我们手工实现。
分配效率:
栈是机器系统提供的数据结构,计算机会在底层堆栈提供支持,分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,他的机制是很复杂的。
问题十:一般情况下堆栈中堆和栈是怎么分配的 堆和栈的区别 一、预备知识―程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)― 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 *** 作方式类似于数据结构中的栈。 2、堆区(heap) ― 一般由程序员...
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)