1、linux下典型的进程空间
linux下一个典型的进程空间如下:
为什么进程还要区分栈和堆,stackoverflow上的一个回答非常好:http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap,主要意思如下:
stack:计算架构中的堆栈是以先到先出(LIFO)方式添加或删除数据的内存区域。
1、创建的变量出了作用域,自动释放;
2、相比较heap的分配简单高效
3、有固定大小,超出会报溢出错误
4、明确固定大小的情况下,可以在编译的时候就确定
heap
1、需要手动释放,其生命周期和手动释放时间有关
2、分配比较慢
3、可以按照程序的需求申请管理
4、动态的申请和释放
栈大小是有默认值的,如果申请的临时变量太大的话就会超过栈大小,造成栈溢出
编译期限制栈大小,和系统限制栈深度根本是两回事。系统限制栈深是限制进程主线程的栈深,限制的是整个函数调用链的最大栈深,这个栈深是函数调用链上各个函数栈帧大小之和。编译期限制栈大小是限制单个函数栈帧的大小。
栈的大小可以修改的。在应用程序我们经常需要定义大的数组,数组定义成局部变量非静态变量,那么数组就会在栈上分配,当数组超过默认栈的大小时,会引起非常内存访问
linux下的堆栈大小受环境变量设置
ulimit -a #显示当前用户的栈大小
ulimit -s 32768 #将当前用户的栈大小设置为32M bytes
2、JVM中stack的结构
jvm中栈保存的是线程运行调用方法的局部变量、被调用进来的参数、它的返回值、以及运算的中间结果等等。java的栈是一帧为单位保存线程的运行状态,线程私有数据。虚拟机对java栈执行的只有二种操作,以帧为单位的入栈和出栈。
java的栈和帧在内存不必须是连续的,珍可以分布在连续的栈里,也可以分布在堆里,或者二者兼而有之,Java栈和帧的实际数据结构由虚拟机的实现者决定。
注意进程中的栈和jvm中的栈不是一个概念,jvm中的栈是个抽象的概念,虚拟机实现程,程序员不可实现,只是一个标准。jvm中的栈是在进程的栈实现,还是在堆实现,还是二者结合,这三种情况都有。
实际上java虚拟机就是一个栈式实现的虚拟机(主要为了摆脱对物理机的依懒,主要是寄存器)。
3、jvm中stack和gc的关系
虚拟机进行gc的时候,是否要对jvm的stack进行gc?因为stack保存的方法的参数和局部变量,调用完成后会自动释放,如果申请了堆对象,在stack也只保留了一个引用,所以,这些内容在调用完成后会自动释放,无需GC来做繁琐的工作,GC只对stack申请的堆对象进行管理。stack有自己的内存管理机制,虚拟机的实现者一般都将其于GC分开。老外有二段经典的回答不错:
观点1:
Garbage collection is a method of deallocating memory that isn't being used anymore. Sometimes the "isn't being used anymore" part is tricky. With the stack, as soon as a function returns, we can be confident (excepting programmer error) that the local variables aren't being used anymore, so they are deallocated automatically at that time in nearly every language/runtime.
观点2:
The stack is called a "stack" precisely because it is a zone of memory which is managed with a "stack policy", aka LIFO (as Last In, First Out). If allocation on the stack was not done in "the stack way" it would not be called a stack but heap.
Garbage Collection was invented in order to cope with the problem of allocating things on a heap, i.e. such that you cannot predict which parts will be released first. GC is meant for memory allocation problems where stack management is not sufficient.
4、参考文档:
http://stackoverflow.com/questions/2447504/is-the-stack-garbage-collected-in-java
http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
http://stackoverflow.com/questions/31145052/difference-between-call-stack-and-thread-stack
http://stackoverflow.com/questions/1762418/what-resources-are-shared-between-threads
https://www.ibm.com/developerworks/cn/linux/kernel/l-thread/
http://hllvm.group.iteye.com/group/forum