您的位置:首页 > 编程语言 > Java开发

Java中堆内存和栈内存

2014-09-05 15:37 204 查看
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存

       在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
      堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。

引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

以上原文地址:http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html

User u = new User();

会在堆内存和栈内存分别创建一个变量,堆内存内创建的是User这个对象,而栈内存内创建的变量是指向堆内存中User的引用变量u。

例外的是Java中的基本类型的变量和指定长度的变量,它的引用变量和值2都是是存在栈内存中的。

从内存的分配角度来看,因为基本类型,已经知道了类型的范围大小,可以进行有效分配,比如int,计算机是知道其范围的,所以直接由系统分配在栈中,无需自己申请!

而新的类型,比如自己定义一个类User,很明显这个类是不知道大小的,应该有程序自己来申请内存空间,所以由堆来分配!

 String是一个特殊的包装类数据。可以用: String str = new String("abc"); String str = "abc";  两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”

比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。 String str1 = "abc"; String str2 = "abc";  System.out.println(str1==str2); //true 可以看出str1和str2是指向同一个对象的。 String str1 =new String ("abc"); String str2 =new String
("abc");  System.out.println(str1==str2); // false  用new的方式是生成不同的对象。每一次生成一个

比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,

下面用例子说明上面的理论。

 

String str1 = "abc"; 

String str2 = "abc"; 

System.out.println(str1==str2); //true 

可以看出str1和str2是指向同一个对象的。

String str1 =new String ("abc"); 

String str2 =new String ("abc"); 

System.out.println(str1==str2); // false 

用new的方式是生成不同的对象。每一次生成一个.

想了解Java内存机制,强烈推荐 参考地址:http://wenku.baidu.com/view/953bfa0ebb68a98271fefac9.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息