java jvm中的堆,栈等内存分配
Content Introduce
Java程序都运行在JVM虚拟机内部
JVM内存 | 内存占用 | 释放 | 优点 | 缺点 | 共享 | 超出 |
---|---|---|---|---|---|---|
堆区(heap) | new创建的对象 | 虚拟机GC | 灵活 | 效率低 | 全局共享 | OOM |
栈区(stack) | 存储局部变量,引用变量 | 自动释放 | 效率高 | 内存有限(递归小心) | 单独线程共享 | SOF |
静态区(static) | 全局 static 数据,常量 | 整个运行期间 | 共享给所有 | 加大内存负担 | 全局共享 |
由于mk的语法原因上面不能写全,更加详细的,见下图
heapAndstack.png
其中静态区其实叫方法区,又叫no-heap 非堆区,它与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。
数据。
sample
public class Sample() {
int s1 = 0;
Sample mSample1 = new Sample();
public void method() {
int s2 = 1;
Sample mSample2 = new Sample();
}
}
Sample mSample3 = new Sample();
说明:
Sample 类的局部变量 s2 和引用变量 mSample2 都是存在于栈中,但 mSample2 指向的对象是存在于堆上的。
mSample3 指向的对象实体存放在堆上,包括这个对象的所有成员变量 s1 和 mSample1,而它自己存在于栈中。
Detailed description
栈内存, 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。
引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,********实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!
参考:
http://blog.csdn.net/codeemperor/article/details/51514448
http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html