Java 堆和栈的详解 - MrWu94/AndroidNote GitHub Wiki

一种说法是分为: 堆(Heap),栈(Stacks)方法区(MethodArea),运行时常量池(RuntimeConstant Pool),本地方法栈(NativeMethod Stacks),PC Register(PC寄存器)。是从抽象的JVM的角度去看的。

在这问题中,我们主要要弄清楚,什么是堆,什么是栈,堆栈内存有什么区别?

Heap内存的分配也叫做动态内存分配,java中运行环境用来分配给对象和JRE类的内存都在堆内存,C/C++有时候可以用malloc或者new来申请分配一个内存。在C/C++可能需要自己负责释放(java里面直接依赖GC机制)。 Stack内存是相对于线程Thread而言的, 在执行函数(方法)时,函数一些内部变量的存储都可以放在栈上面创建,函数执行结束的时候这些存储单元就会自动被释放掉。栈内存包括分配的运算速度很快,因为内置在处理器的里面的。当然容量有限。它保存线程中方法中短期存在的变量值和对Heap中对象的引用等. 区别:堆是不连续的内存区域,堆空间比较灵活也特别大。 栈式一块连续的内存区域,大小是有操作系统觉决定的。堆管理很麻烦,频繁地new/remove会造成大量的内存碎片,这样就会慢慢导致效率低下。对于栈的话,他先进后出,进出完全不会产生碎片,运行效率高且稳定。

我们通常说的内存泄露,GC,是针对Heap内存的. 因为Stack内存在函数出栈的时候就销毁了。 比如说这个类

public class People{
    int a = 1;
    Student s1 = new Student();
    public void XXX(){
        int b = 1;
        Student s2 = new Student();
    }
}

请问a的内存在哪里,b的内存在哪里,s1,s2的内存在哪里?记住下面两句话。

成员变量全部存储在堆中(包括基本数据类型,引用及引用的对象实体),因为他们属于类,类对象最终还是要被new出来的。 局部变量的基本数据类型和引用存储于栈当中,引用的对象实体存储在堆中。因为他们属于方法当中的变量,生命周期会随着方法一起结束。 所以答案就是a,s1,s2对象都堆中,b和s2对象引用在栈中。

参考:http://www.jianshu.com/p/c0e5c13d5ecb