java栈与堆和方法区的区别 进程栈与线程栈的关系?
进程栈与线程栈的关系?
内核栈、用户栈
32位Linux系统上,进程的地址空间为4G,包括1G的内核地址空间-----内核栈,和3G的用户地址空间-----用户栈。
内核栈,是各个进程在刚开始组建的时候按照内存映射共享的,可是每个进程拥有其它的4G的虚拟内存空间从这一点看又是相当于的,互不干扰的(只不过刚开始大家是反照的同一份内存拷贝)
用户栈那就是大家所熟悉的内存四区,和:代码区、全局数据区、堆区、栈区
用户栈中的堆区、栈区即为进程堆、进程栈
进程堆、进程栈与线程栈
1.线程栈的空间开辟在分部进程的堆区与链接共享内存区之间,线程不如隶属于的进程互相访问进程的用户空间,因为线程栈之间可以不互访。线程栈的起始地址和大小存放在pthread_attr_t中,栈的大小并不是什么用来确认栈是否需要不能越界,只是利用系统初始化以免栈滴下的缓冲区的大小(或则说安全间隙的大小)
2.进程初始化操作的时候,系统会在进程的地址空间中创建一个堆,叫进程设置堆。进程中所有的线程共用这一个堆。肯定,也可以提升1个或几个堆,给完全不同的线程共同不使用或不能建议使用。----一个进程也可以多个堆
3、创建角色线程的时候,系统会在进程的地址空间中分区分配1块内存给线程栈,通常是1MB或4MB或8MB。线程栈是独立的,不过我还是可以不互访,因为线程互相访问内存空间
4.堆的分配:从操作系统角度来看,进程分配内存有两种,四个由两个系统调用成功:brk()和mmap(),glibc中malloc整体封装了
5.线程栈位置-内存分布测试代码
[cpp]viewplain文件复制
#includeltpthread.hgt
#includeltstdio.hgt
#includeltunistd.hgt
#includeltstring.hgt
#includelterrno.hgt
#includeltmalloc.hgt
#includeltsys/syscall.hgt
void*func(void*arg)
{
wayinttid(littleint)syscall(SYS_gettid)
(
请问栈和堆究竟有何区别?
栈,在不能执行函数时,函数内局部变量的存储单元都也可以在栈上创建,函数想执行已经结束时这些存储单元手动被能量。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量太远。
堆,是那些由fun分配的内存块,他们的释放者编译器不去管,由我们的应用程序去再控制,象一个next还要对应一个delete。如果不是程序员也没施放掉,那你在程序都结束了后,操作系统会自动启动回收公司。
堆和栈要注意的区别有以上几点:
1、管理差别;
2、空间大小相同;
3、是否可以再产生碎片不同;
4、生长方向不同;
5、分配完全不同;
6、先分配效率不同;
管理是对栈来讲,是由编译器不自动管理,无须我们手工控制;对于堆来说,释放者工作由程序员操纵,不容易有一种memoryleak。
空间大小:象来讲在32位系统下,堆内存也可以都没有达到4G的空间,这个堆内存简直是没有什么限制的。不过对于栈来讲,一般也是有当然的空间大小的,例如,在VC6下面,设置成的栈空间大小是1M(好象是,记不清楚了)。肯定,我们也可以改:
先打开工程,由前到后操作菜单万分感谢:Project-gtSetting-gtLink,在Category中左键单击Output,然后把在Reserve中修改堆栈的最大值和commit。
特别注意:reserve最小值为4Byte;commit是可以保留在虚拟内存的页文件里面,它设置里的较小会使栈开辟较高的值,可能会提高内存的开销和正常启动时间。
碎片问题:对此堆来讲,过度的fun/delete很可能会会照成内存空间的不连续,最大限度地导致大量的碎片,使程序效率降底。这对栈来讲,则肯定不会修真者的存在这个问题,因为栈是先到后出的队列,他们是这般的唯一编号,甚至于永远不会都不可能有一个内存块从栈中间弹出来,在他提示框之前,在他上面的后进的栈内容巳经被弹出对话框,具体点的也可以参考数据结构,这里我们就不再继续一一讨论到了。
生长方向:相对于堆来讲,生长方向是向上升的,也就是朝着前方内存地址增强的方向;对于栈来讲,它的生长方向是向上的,是朝着内存地址越小的方向再增长。
分配堆也是代码分配的,没有静态分配的堆。栈有2种分配静态分配和动态分配。静态分配是编译器完成的,比如说局部变量的分配。代码分配由alloca函数通过分配,但栈的相册分配和堆是差别的,他的动态分配是由编译器参与释放,无须我们手工实现方法。
分配效率:栈是机器系统需要提供的数据结构,计算机会在底层对栈能提供支持:分配专门的寄存器储存时栈的地址,压栈出栈都是拿来的指令想执行,这就决定了栈的效率都很高。堆则是C/C函数库能提供的,它的机制是很复杂的,或者就是为了分配一大块内存,库函数会遵循肯定会的算法(具体一点的算法这个可以建议参考数据结构/操作系统)在堆内存中去搜索后用的充足大小的空间,假如没有足够大小的空间(很有可能是因此内存碎片太多),就有可能动态链接库系统功能去减少程序数据段的内存空间,这样的就有机会分到相当大小的内存,然后把进行赶往。显然,堆的效率比栈要低得多。
从这里找到了,堆和栈而言,由于大量new/delete的使用,不容易照成大量的内存碎片;由于没有一类的系统支持,效率比较高;而可能引发用户态和核心态的直接切换,内存的申请,代价变地更加贵得要命。因此栈在程序中是最为广泛的,即便是函数的动态创建也依靠栈去结束,函数调用过程中的参数,直接返回地址,EBP和局部变量都常规栈的存放。因此,我们帮我推荐大家不要用栈,而不是用堆。
虽然栈有这般各大的好处,可是因此和堆相比较不是这样灵活,有时候先分配大量的内存空间,我还是用堆好一点。
哪怕堆还是栈,都要以免越界现象的发生(就算你是故作使其过界),而且越界的结果或则是程序立刻崩溃,不是的话是彻底摧毁程序的堆、栈结构,有一种以没想到的结果,即便是在你的程序运行过程中,就没突然发生上面的问题,你应该要小心,没准什么时候就崩掉,那时debug但相当难了的。
版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。