回顾JAVA中栈堆的知识认解

首先回顾一下栈与堆在计算机运行中所存在的定义与用处。

堆(heap)

 (1)堆总是一颗完全二叉树,深度为K,除了k层外,1~k-1层的结点数都达到最大值,k层所有的节点都连续集中在最左边的就是完全二叉树

(2)堆 不是在程序编译时申请内存的,而是在程序运行时向操作系统申请内存空间,即动态分配内存空间,一般是申请/给予的过程;

(3)堆通常可被看作一棵树的数组对象,如堆排序;

(4)用来存放由 new 创建的对象和数组,由程序员分配和释放,如果程序员不释放,最终会被系统回收;

(5)存放在二级缓存,生命周期由垃圾回收算法决定,不是一旦成为孤儿对象就立刻被回收的。

 

栈(stack)

(1)栈,又名栈堆,是线性表;

(2)仅能在链表的一端做插入/删除运算,一端为栈顶,另一端就是栈底了;

(3)数据是先进后出的数据结构 ,就像一个水杯【或水桶】,先进来的在底部,最后才能出去;

(4)由操作系统自动分配和释放,用于存放函数的参数值 和局部变量的值;

(5)存放在一级缓存,调用完毕立即释放。

 

看一段关于数组的代码:

 

    
    public void t2() {
        int[] num = null;
        num = new int[2];
        num[0] = 1;
        num[1] = 2;
        System.out.println(Arrays.toString(num));
    }

得出的结果是:{1,2}

 我们知道,栈是用于存放函数的参数值 和局部变量的值 ,

那么在这段代码中 , 局部变量 num 将会存在栈里面 ,

new 表示开辟存储空间 ,那么到底在哪里开辟存储空间呢?

其实是在堆里面 ,

new int[2] 表示在堆里面 开辟一个长度为2 的数组 空间 ,此时数组每个元素 的私有空间 是空的。

通过赋值  num =  使得 栈 元素 num 的 数据指针指向 堆 里长度为2 的数组 空间 的地址 ,

也就是说 ,栈是存储 变量的名称 ,而堆是存储变量的 对象内容,

当赋值的时候 ,将会改变堆中数组的值。

 

再看一段代码:

public void t2() {
    int[] num = null;
    num = new int[2];
    num[0] = 1;
    num[1] = 2;
    System.out.println(Arrays.toString(num));
    int[] data = null;
    data = num;
    System.out.println(Arrays.toString(data));
    data[0]=10;
    System.out.println(Arrays.toString(data));
    System.out.println(Arrays.toString(num));
}

 

得出的结果是:

{1,2}

{1,2}
{10,2}

{10,2}

 

 多了 data = num;  进行数组赋值 ,

那么底层到底是怎么实现的?难道又新建了一个栈名为data的变量,在队列又开辟了个空间然后拷贝数据么?

实际上并非如此。

int[] data = null;表示新定义了个 名叫 data的局部变量 ,存在栈里 新分配的一个空间中,此时data 没有对应的堆内容,

当 data = num;  时 将会把 num指向的堆内容地址传给data ,data将会指向该堆地址,也就是说,两个栈空间会指向同一个 堆空间

将会共同支配同一个 堆 的内容。

data[0]=10; 则是对该堆空间数组的第一个元素赋值 ,将原值为1 改成了 10 。

打印结果 【10 ,2】没有问题。

然后再次打印 num ,结果仍然是 【10 ,2】,

可证明 两个栈空间确实 是 指向了 同一个 堆空间 ,即数据共享了。

如果仅仅定义变量,却不赋值,仅仅会在栈开辟空间存储变量名称 ,如果给变量赋值,将会把值存在堆中 ,栈会指向这个堆的地址

这就是"栈堆"这一称呼的由来。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值