看了好几篇关于 堆和栈区别介绍的文章,打算根据自己的理解浅显的记录下,也是为了自己对 堆和栈加深一点印象
栈
1、会分配连续的内存空间
2、一般是存放参数值、局部变量(基本类型变量和引用变量)
3、存取方式:先进后出
堆
1、不连续的内存空间
2、一般是存放实例化的对象
3、存取方式:先进先出
还有 静态区,存放静态变量的
以及常量区
下面这部分是从其他网站摘录过来的 地址是http://www.tuicool.com/articles/7NR7NzV
1 public class TestMemory { 2 3 public static void main(String[] args) { 4 int i = 666;//line1 5 Object object = new Object();//line2 6 TestMemory testMemory = new TestMemory();//line3 7 testMemory.test(object);//line4 8 } 9 //line5 10 private void test(Object params){//line6 11 String str = params.toString();//line7 12 System.out.println(str);//line8 13 } 14 } 15 //line9
下面这张图片展示了上面代码的内存信息。
1、当程序运行时,JVM会先加载运行时的类和我们自己写的类信息,这些类信息加载后存在堆内存当中。
2、接着进入到main方法,第一行line1创建了一个基本数据类型i=666,所以创建了一个main方法的内存块,它里面同时存放了i=666;
3、接着line2和line3的位置
Object object = new Object();
TestMemory testMemory = new TestMemory();创建了两个局部变量,object和testMemory,同时在堆里存放了两个新的对象Object和TestMemory。(每次我们new 一个对象都会在堆区产生一块内存区给它分配空间)。同时object和testMemory引用了new出来的对象。
4、现在到了line4,test方法了,当调用到test方法的时候,在栈的顶层创建了一块test()方法的内存区( 我们说过栈的特点就是后进先出 ),由于在 Java里的传递是值传递,所以就有了参数object产生了一个新的引用。
5、最后调用了toString产生了一个字符串常量存放在了String pool里,并且str 引用了它。(如果你有String类感兴趣,你可能喜欢 》 Java你可能不知道的事系列1_String类
6、当test方法结束,它里面的变量也就被GC回收掉了。接着main方法也就结束。Java在运行时释放这些内存并结束程序的运行。
总结
1、当一个对象被创建,总是会在堆内存为它分配空间并且存储,如果有赋值就会将变量引用到对象。而栈内存就是存放这些引用对象的局部变量。
2、栈内存的生命周期很短,而堆内存从程序执行开始到结束一只都需要工作。因为栈内存没当执行完一个方法,它们所占的内存区就会被释放。而堆内存里的对象只有在没有任何变量引用到它的时候才可能会被释放。
3、栈内存大小相比于堆内存非常小。但是它相对于堆内存又比较快。