zoukankan      html  css  js  c++  java
  • 堆内存 和 栈内存的简单理解

    看一个例子:

    var a =3;
    var b = a;
    a=1;
    console.log(a,b);
    var arr1 = [1,2,3,4];
    var arr2 = arr1;
    arr1.push(5);
    console.log(arr2);
    

     第一个console.log(a,b) 1 3;

    第二个console.log(arr2)  [1,2,3,4,5]

    这个问题很奇怪。为什么 b的值变成了 a 原来的值,没有随着a的重新赋值而变化,而 arr2却随着 arr1的变化而变化呢?

    原因是;JS值分为两种 :原始值引用值

    原始值:String,Undefined、Null、Boolean、Number

    引用值:Object  Array Function Date RegExp

    所以很显然了,a 和 b 是属于Number类型的,即原始值;而 arr1 和 arr2是属于 Array 类型的,即引用值;

    原始值存储在 中;

    引用值存储在 中;并且 在 栈 中存储了 堆 的地址;如下图所示:

    所以,两种值的存储方式不同,导致了问题的发生。

    原始类型中:

    var a =3; //在栈中 开辟空间存放3 并且名称为a
    var b = a; // 在栈中 开辟空间存放复制 a 的值 并且名称为b
    a=1; //在栈中 开辟空间存放3 并且名称为a,原来的地址 a 改为默认的地址,这里是默认的1008,如上图所示;
    console.log(a,b);
    

     引用类型中:

    var arr1 = [1,2,3,4];//在堆中 开辟空间存放[1,2,3,4]   并在栈中开辟空间存放 指向对中的地址,栈中名称为 arr1
    var arr2 = arr1;// 在栈中开辟空间存放 指向对中的地址,栈中名称为 arr2  这里 arr2存放的堆地址 与 arr1的堆地址相同。
    arr1.push(5);
    console.log(arr2);
    

    那么如果arr1重新赋值,arr2 会随之 arr1的赋值而改变吗?

    其实是不会的,原因是,在堆中,arr1的存储过程中,需要重新再开辟一个空间来存放 arr1最新的一次赋值,当然arr1在栈中指向堆的引用地址就发生了改变,这个时候,arr2在栈中的引用地址 和 arr1的地址不同。所以,这个时候,arr2 不会随着 arr1的赋值而改变。

    再看一个Java中的例子:

    Java一维数组的内存解析

    这个例子输出结果是null;

    如果是基本数据类型

    1     @Test
    2     void test() {
    3         int a = 0;
    4         int b = a;
    5         a = 2;
    6         System.out.println(b);
    7                 
    8     }

    输出结果是0;因为b在栈空间中存的是0,不是地址值;

    再看一个对象的内存解析:

    Java知识点补充:

      一、栈(Stack ),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char、short、int、float、  long、double)、对象引用 (reference类型,它不等同于对象本身,是对象在堆内存的首地址)。方法执行完,自动释放。

    •  栈:先进后出
    • 方法中定义的变量都是局部变量,存在于栈空间中

       二、堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在 Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。

    • 将new出来的结构(比如:数组、对象)加载在对空间中。
    • 补充:对象的属性(非static的)加载在堆空间中

      三、方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

      注意点:编译完源程序以后,生成一个或多个字节码文件。
      我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。

    参考地址:https://www.cnblogs.com/zhufeng123/p/12263011.html

  • 相关阅读:
    sap 登陆增强
    去除字符串末尾的空格
    abap 动态控制状态栏按钮
    首页菜单显示TCODE
    me23n去价格
    abap 导出数据到excle,粘贴复制法
    TCODE找相應的BAPI(主要是找到包PACKAGE)
    Sap自动编号工具(SNRO)
    jQuery 实现置顶效果
    order by 不能使用别名
  • 原文地址:https://www.cnblogs.com/lixiuming521125/p/10867062.html
Copyright © 2011-2022 走看看