javascript中内存的理解

javascript中内存的理解

js中的数据类型分为基本数据类型和引用数据类型,即原始值和引用值,基本数据类型包括number、string、boolean、null、undefined;引用数据类型包括Object、Function、Array等

基本数据类型的变量名和变量值在内存中位置都为栈,是存储在栈中的简单数据类型;引用数据类型变量名存储在内存的栈中,变量值存储在堆中。对于引用数据类型,变量名只是存储在栈中的一个指针

  • 栈:数据类型的大小和生存期固定,占用内存空间小,存取数度快,仅次于寄存器,主要存储基本数据类型
  • 堆:数据类型的大小和生存期不固定,占用内存空间大,存取数度慢,主要存储引用数据类型

如下代码

var num = 10;
var str = "hello";
var flag = true;
var obj = new Object();
var arr = ["a","b","c"];
var person = new Person(100,"zyb",25)
function Person(id,name,age){
    this.id = id;
    this.name = name;
    this.age = age
}

以上代码在内存中的位置分析图,如下栈中的obj指向堆中的Object,person指向第三部分,array指向第二部分javascript

内存
num:10
str:"hello"
flag:true
obj
person
array
Object
length:3
0:'a'
1:'b'
2:'c'
id:100
name:"zyb"
age:25
[[prototype]]
...

javascript有本身的垃圾回收机制,js解释器会自动分配和回收内存;

  • 须要的时候分类配内存
  • 对内存读写操做
  • 不须要的时候释放内存

如下是分配内存空间的几种状况:java

  • 变量初始化
  • 函数调用

何时释放内存?

原理上一块内存不须要了,就会被释放掉,可是怎么肯定一块内存不须要?一个对象不被引用就会被释放,一个对象被引用一次,引用计数就加1;算法

var outerObj = {//外层对象
    innerObj:{//内层对象
        msg:"hello"
    }
}
//内层对象被外层对象引用,外层对象被outerObj引用
//内层对象引用计数:1
//外层对象引用计数:1
//内层对象和外层对象不会被垃圾回收

var tempObj = outerObj
//内层对象引用计数:1
//外层对象引用计数:2
//内层对象和外层对象不会被垃圾回收

var outerObj = 1
//内层对象引用计数:1
//外层对象引用计数:1
//内层对象和外层对象不会被垃圾回收

var _tempObj = tempObj.innerObj
//内层对象引用计数:2
//外层对象引用计数:1
//内层对象和外层对象不会被垃圾回收

var tempObj = 2
//内层对象引用计数:1
//外层对象引用计数:0
//内层对象不会被垃圾回收
//外层对象会被垃圾回收

var _tempObj = 3
//内层对象引用计数:0
//外层对象引用计数:0
//内层对象会被垃圾回收
//外层对象会被垃圾回收

引用计数缺点:

function f(){
    var o = {};
    var o2 = {};
    o.a = o2; // o 引用 o2
    o2.a = o; // o2 引用 o

    return “ok”;
}

f();

分析:函数

上面f函数执行完后,里面的变量按理来讲都会被释放,可是o和o2互相调用,两者的引用计数都不为0,所以两者都不会被收回,从而致使内存泄漏this

标记清除算法

当一个对象不可达的时候,这个对象就会被释放,上面o和o2不被任何对象引用,即处于“不可达”状态,能够被回收prototype

函数传递参数,按值传递

function box(num){   //按值传递
    num+=10;
    return num;
}

var num = 10;
var result = box(num);
console.log(result); //20
console.log(num); //10

执行环境及做用域

var name ="zhangsan";

function setName(){
    name = "lisi"
}
setName();
console.log(name)//lisi

经过传参

var name ="zhangsan";

function setName(name){
    console.log(name)//lisi
}
setName("lisi");
console.log(name)//zhangsan
相关文章
相关标签/搜索