博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
内存管理
阅读量:4097 次
发布时间:2019-05-25

本文共 2130 字,大约阅读时间需要 7 分钟。

  • 在使用垃圾回收的编程环境中,开发者通常无须关心内存管理。不过,JavaScript运行在一个内存管理与垃圾回收都很特殊的环境。分配给浏览器的内存通常比分配给桌面软件的要少很多,分配给移动浏览器的就更少了。这更多出于安全考虑而不是别的,就是为了避免运行大量JavaScript的网页耗尽系统内存而导致操作系统崩溃。这个内存限制不仅影响变量分配,也影响调用栈以及能够同时在一个线程中执行的语句数量。
  • 将内存占用量保持在一个较小的值可以让页面性能更好。优化内
    存占用的最佳手段就是保证在执行代码时只保存必要的数据。如果数
    据不再必要,那么把它设置为 null ,从而释放其引用。这也可以叫
    作解除引用。这个建议最适合全局变量和全局对象的属性。局部变量
    在超出作用域后会被自动解除引用

1、通过const和let声明提升性能

因为 const 和 let 都以块(而非函数)为作用域,所以相比于使用 var ,使用这两个新关键字可能会更早地让垃圾回收程序介入,尽早回收应该回收的内存。在块作用域比函数作用域更早终止的情况下,这就有可能发生。

2、隐藏类和删除操作

function Article() {
this.title = 'Inauguration Ceremony Features Kazoo Band';}let a1 = new Article();let a2 = new Article();a2.author = 'Jake';
  • 此时两个 Article 实例就会对应两个不同的隐藏类。根据这种操作的频率和隐藏类的大小,这有可能对性能产生明显影响。
  • 解决方案就是避免JavaScript的“先创建再补充”(ready-fireaim)式的动态属性赋值,并在构造函数中一次性声明所有属性。优化为
function Article(opt_author) {
this.title = 'Inauguration Ceremony Features Kazoo Band'; this.author = opt_author;}let a1 = new Article();let a2 = new Article('Jake');
  • 这样,两个实例基本上就一样了(不考虑 hasOwnProperty 的返回值),因此可以共享一个隐藏类,从而带来潜在的性能提升。
function Article() {
this.title = 'Inauguration Ceremony Features Kazoo Band'; this.author = 'Jake';}let a1 = new Article();let a2 = new Article();// 共享一个隐藏类,这样,两个实例基本上就一样了(不考虑 hasOwnProperty 的返回值)delete a1.author;// 使用 delete 关键字会导致生成相同的隐藏类片段,既不再共享一个隐藏类// 在代码结束后,即使两个实例使用了同一个构造函数,它们也不再共享一个隐藏类。// 动态删除属性与动态添属性导致的后果一样。a1.author=null// 最佳实践是把不想要的属性设置为 null 。这样可以保持隐藏类不变和继续共享,// 同时也能达到删除引用值供垃圾回收程序回收的效果。

3、内存泄漏

  • 例1、
function setName() {
name = 'Jake'; }
  • 此时,解释器会把变量 name 当作 window 的属性来创建(相当于 window.name = ‘Jake’ )。可想而知,在 window 对象上创建的属性,只要 window 本身不被清理就不会消失。这个
    问题很容易解决,只要在变量声明前头加上let、cont、var即可,这样变量就会在函数执行完毕后离开作用域。
  • 例2、定时器的回调通过闭包引用了外部变量
let name = 'Jake';setInterval(() => {
console.log(name);}, 100);

只要定时器一直运行,回调函数中引用的 name 就会一直占用内存。垃圾回收程序当然知道这一点,因而就不会清理外部变量。使用JavaScript闭包很容易在不知不觉间造成内存泄漏。

  • 例3
let outer = function () {
let name = 'Jake'; return function () {
return name; };};
  • 这会导致分配给 name 的内存被泄漏。以上代码创建了一个内部闭包,只要 outer 函数存在就不能清理 name ,因为闭包一直在引用着它。假如 name 的内容很大(不止是一个小字符串),那可能就是个大问题了。

四、静态分配与对象池

注意 静态分配是优化的一种极端形式。如果你的应用程序被垃圾回收严重地拖了后腿,可以利用它提升性能。但这种情况并不多见。大多数情况下,这都属于过早优化,因此不用考虑。

转载地址:http://ydqii.baihongyu.com/

你可能感兴趣的文章
【批处理】windows环境将文件隐藏到图片中
查看>>
【批处理】windows环境将文件放置在虚拟盘
查看>>
【Word】一些实用的小技巧
查看>>
【Excel】设置自定义单元格格式
查看>>
【Python】logging内置模块基本使用
查看>>
【Python】字典dict类型转换为列表list类型
查看>>
【Python】xlwt和xlrd模块写入和读取.xls版本EXCEL
查看>>
【Python】pymysql模块处理Mysql数据库
查看>>
【Python爬虫】使用urllib.request下载已知链接的网络资源
查看>>
Fiddler在PC/台式对Android进行抓包
查看>>
【Python爬虫】爬取微信公众号文章信息准备工作
查看>>
【Python爬虫】微信公众号历史文章和文章评论API分析
查看>>
【Python】Python简介和Python解释器
查看>>
多任务场景下单线程异步多线程多进程
查看>>
【Python】单线程异步多线程多进程实例
查看>>
【Python爬虫】requests与urllib库的区别
查看>>
【教育】世界上最伟大的25个教育法则
查看>>
【测试工具】在linux测试环境安装bug管理工具禅道
查看>>
【测试工具】在linux测试环境访问禅道数据库
查看>>
【Python】提升Python程序性能的好习惯2
查看>>