zoukankan      html  css  js  c++  java
  • js的栈与堆

    js的栈与堆

    堆heap与栈stack基本是所有的程序语言中都带有的,它将数据分配到内存空间来完成各种调用。(当然了,内存里除了heap和stack还有常量池。)

    为啥要有heap和stack?

    为什么会有栈内存和堆内存之分?

    通常与垃圾回收机制有关。为了使程序运行时占用的内存最小。

    当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。因此,所有在方法中定义的变量都是放在栈内存中的;

    当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。

    栈中存储的是基础变量以及一些对象的引用变量,基础变量的值是存储在栈中,而引用变量存储在栈中的是指向堆中的数组或者对象的地址,这就是为何修改引用类型总会影响到其他指向这个地址的引用变量。

    js和java类似,有垃圾回收机器自动释放那些不需要的。在java中,变量超出作用域后,便会被销毁,引用变量被销毁后,数组和对象依旧占据着堆内存的空间。数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因。

    栈的特点

    栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

    Java中的数据类型有两种。 一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。

    另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义
    int a = 3; int b = 3;编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

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

    js中除了null和undefined,其他值都可以拥有方法。数组和对象属于可变类型,number,boolean,null,undefined都是不可变的,string也是同样,虽然可以看作字符组成的数组,但它是不可变的,只会被包含新值的字符串替换。

    var str = 'hello';
    str += ' world'; //这个操作其实是这样,创建一个11个字符长度的新字符串,然后填充'hello'和' world',最后销毁这两个字符串,完成值的变更。
    log(str)//hello world
    

    栈和堆的溢出

    如果想要堆溢出,比较简单,可以循环创建对象或大的对象;
    如果想要栈溢出,可以递归调用方法,这样随着栈深度的增加,JVM 维持着一条长长的方法调用轨迹,直到内存不够分配,产生栈溢出。

  • 相关阅读:
    刘墉写给女儿的忠告
    HTML & CSS 小总结
    [LeetCode] 151. Reverse Words in a String 翻转字符串中的单词
    [LeetCode] 340. Longest Substring with At Most K Distinct Characters 最多有K个不同字符的最长子串
    [LeetCode] 127. Word Ladder 单词阶梯
    [LeetCode] 300. Longest Increasing Subsequence 最长递增子序列
    [LeetCode] 354. Russian Doll Envelopes 俄罗斯套娃信封
    [LeetCode] 218. The Skyline Problem 天际线问题
    [LeetCode] 407. Trapping Rain Water II 收集雨水 II
    [LeetCode] 309. Best Time to Buy and Sell Stock with Cooldown 买卖股票的最佳时间有冷却期
  • 原文地址:https://www.cnblogs.com/mydia/p/6713671.html
Copyright © 2011-2022 走看看