一、栈(stack)和堆(heap)
栈(stack):是栈内存的简称,栈是自动分配相对固定大小的内存空间,并由系统自动释放,栈数据结构遵循FILO(first in last out)先进后出的原则,较为经典的就是乒乓球盒结构,先放进去的乒乓球只能最后取出来。
堆(heap):是堆内存的简称,堆是动态分配内存,内存大小不固定,也不会自动释放,堆数据结构是一种无序的树状结构,同时他还满足Key-valve键值对的存储方式:我们只用知道key名,就能通过key查找到对应value。比较经典的就是书架存书的例子,我们知道书名,就可以找到都对应的书籍。
栈的特点:开口向上、速度快、容量小;堆的特点:速度稍慢、容量比较大;
二、基本类型和引用类型
基本数据类型:U你defined、String、Boolean、Null、Number,都是直接按值存放在栈内存中,占用的内存空间的大小是确定的,并由系统自动分配和自动释放。这样带来的好处就是,内存可以及时得到回收,相对于堆来说,更加用以管理内存空间。
引用数据类型:指哪些可能由多个值构成的对象,如对象(Object)、数组(Array)、函数(Function),他们是通过拷贝和new出来的,这样的数据存储于堆中。
三、传值和传址的区别
基本类型:采用的是值传递。
引用类型:则是地址传递。
引用类型的数据的地址指针是存储于栈中的,将存放在栈内存中的地址赋值给接收的变量。当我们想要访问引用类型的时候,需要先从栈中获得对象的地址指针,然后,再通过地址指针找到堆中的所需要的数据(保存再堆内存中,包含引用类型的变量实际上保存的不是变量本身,二十指向该对象的指针)。
四、内存分配垃圾回收
1、内存分配:
a.栈内存:线性有序存储,容量小,系统分配效率高。
b.堆内存:首先要在堆内存新分配存储区域,之后又要把指针存储到栈内存中,效率相对就要低一些。
2、垃圾回收:
a.栈内存:变量基本上用完就回收了,相对堆来说存取速度会快,并且栈内存中的数据是可以共享的。
b.堆内存:堆内存中的对象不会随方法的结束而销毁,就算方法结束了,这个对象也可能会被其他引用变量所引用(参数传递)。创建对象是为了反复利用(因为对象的创建成本通常较大),这对象将保存到运行时数据区(也就是堆内存)。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才能在合适的时候回收它、
五、浏览器垃圾回收机制
1、浏览器的垃圾回事机制
a.垃圾回收的概念
垃圾回收:JavaScript代码运行时,需要分配内存空间来储存变量和值。当变量不在参与运行时,就需要系统收回被占用的内存空间,这就是垃圾回收。
2、回收机制
1、JavaScriot具有自动垃圾回收机制,会定期对那些不再使用的变量、对象所占用的内存进行释放,原理就是找到不再使用的变量,然后释放掉其占用的内存。
2、JavaScript中存在两种变量:局部变量和全局变量。全局变量的生命周期会持续要页面卸载;而局部变量声明在函数中,它的生命周期从函数执行开始,直到函数执行结束,在这个过程中,局部变量会在堆或栈中存储他们的值,当函数执行结束后,这些局部变量不再使用,他们所占有的空间就会被释放。
3、不过,当局部变量被外部函数使用时,其中一种情况就是闭包,在函数执行结束后,函数外部的变量依然指向函数内部的局部变量,此时局部变量依然在被使用,所以不会回收。
3、垃圾回收的方式
浏览器通常使用的垃圾回收方法有两种:标记清楚,引用计数。
1、标记清楚;
a.标记清除时浏览器常见的垃圾回收方式,当变量进入执行环境时,就标记这个变量‘进入环境’,被标记为‘进入环境’的变量是不能被回收的,因为他们正在被使用。当变量离开环境时,就会被标记为‘离开环境’,被标记为‘离开环境’的变量会被内存释放。
b.垃圾收集器在运行的时候会给储存在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因时环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间。
2、引用计数
a.另外一种垃圾回收机制就是引用计数,这个用的相对较少。引用计数就是耿总记录每个值被引用的次数。当声明了一个变量并将一个引用类型复制给该变量时,则这个值的引用次数就是1.相反,如果包含堆这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1.当这个引用次数变为0时,说明这个变量已经没有价值,因此,再在回收期下次再运行时,这个变量所占有的内存空间就会被释放出来。
b.这种方式会引起循环引用的问题:例如:obj1和obj2通过属性进行相互引用,两个对象引用次数都是2.当使用循环计数时,由于函数执行完后,两个对象都离开作用域,函数执行结束,obj1和obj2还将继续存在,因此他们引用的次数永远不会是0,就会引起循环引用。
function(){
let obj = {};
let obj2 = {};
obj1.a = obj2;
obj2.a = obj1;
}
这种情况下,就要手动释放变量占用的内存:
obj1.a=null'
obj2.a=null;
3、减少垃圾回收
虽然浏览器可以进行垃圾自动回收,但是当代码比较复杂是,垃圾回收所带来的代价比较打,所以应该尽量减少垃圾回收。
a.对数组进行优化:在清空一个数组时,最简单的方法就是给其赋值为[],但是于此同时会创建一个新的空对象,可以将数组的长度设置为0,以此来达到清空数组的目的。
b.对object进行优化:对象尽量复用,对于不再使用的对象,就将其设置为null,尽快被回收。
c.对函数进行优化:在循环中的函数表达式,如果可以服用,尽量放在函数的外面。
4、那些情况会导致内存泄漏
a.意外的全局变量:由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留在内存中无法被回收。
b.被遗忘的计时器或回调函数:设置了setInterval定时器,而忘记取消它,如果循环函数有对外部变量的引用的化,那么这个变量会被一直留在内存中,而无法被回收。
c.脱离DOM的引用:获取一个DOM元素的引用,而后面这个元素被删除,由于一直保留了对这个元素的引用,所以它也无法被回收;
d.闭包:不合理的使用闭包,从而导致某些变量一直被留在内存当中。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。