堆和栈

堆和栈都是Java用来在RAM中存放数据的地方。

(1)Java的堆是一个运行时数据区,类的对象从堆中分配空间。这些对象通过new等指令建立,通过垃圾回收器来销毁。

(2)堆的优势是可以动态地分配内存空间,需要多少内存空间不必事先告诉编译器,因为它是在运行时动态分配的。但缺点是,由于需要在运行时动态分配内存,所以存取速度较慢。

1)栈中主要存放一些基本数据类型的变量(byte,short,int,long,float,double,boolean,char)和对象的引用。

(2)栈的优势是,存取速度比堆快,栈数据可以共享。但缺点是,存放在栈中的数据占用多少内存空间需要在编译时确定下来,缺乏灵活性。
举例说明栈数据可以共享

int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况,即共享了3这个栈数据。.

java的八种引用类型(Byte Short、Integer、Long、Character、Boolean、Float、Double),除Float及Double以外,其它六种都实现了常量池,但是他们只在大于等于-128且小于等于127时才能使用常量池,如果不在此范围内,则会new一个出来,保存在堆内存中。

    Integer i1 = 100, i2 = 100, i3 = 150, i4 = 150;
    //涉及到IntegerCache 这个内部类的问题
    // true 如果整型字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用
    System.out.println(i1 == i2);
    // false 生成两个对象.
    System.out.println(i3 == i4);

    Long f1 = 100l, f2 = 100l, f3 = 150l, f4 = 150l;
    //涉及到Cache 这个内部类用作缓存的问题
    System.out.println(f1 == f2);       // true 如果Long字面量的值在-128到127之间而是直接引用
    System.out.println(f3 == f4);       // false 生成两个对象.

特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

 

 

 

 

 

代码一:

    public class Demo {
        public static void main(String[] args) {    
            String s1 = "china";
            String s2 = "china";
            String s3 = "china";
            String ss1 = new String("china");
            String ss2 = new String("china");
            String ss3= new String("china");
        }
    }

思考:分布情况会怎样?

s1、s2、s3都是基本类型的局部变量,

ss1、ss2、ss3都是String对象的引用,

所以都在栈区

 

而"china"是常量,

所以放在常量区

 

而三个new的对象,

自然就放在堆区
代码二:

    class BirthDate{
        private int day;
        private int month;
        private int year;
        public BirthDate(int d, int m, int y) {
            day = d;
            month = m;
            year = y;
        }
        //省略get.set方法.
    }
    public class Test{
        public static void main(String[] arg) {
            int date = 9;
            Test test = new Test();
            test.change(date);
            BirthDate d1= new BirthDate(7,7,1970);
        }
        public void change(int i){
            i = 1234;
        }
    }

思考:内存如何分布?

从执行代码部分看,

date, test, i, d1, d,m、y.

都属于基本类型的局部变量, 因此都分配到栈区。

而Test(),Birthdate()两个都是new出来的对象,因此都放在堆区。
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值