zoukankan      html  css  js  c++  java
  • 内存分配以及优化

    1、前言

    本来我是用js编程一道题,浏览器报错RangeError: Maximum call stack size exceeded,百度了很多js内存、栈的知识,找了几十个页面的答案,只能说是不如人意。每个文章几乎相同,上来就吧啦吧啦解释一堆堆栈的概念,然后就讲基本变量保存在栈内,引用类型保存在堆内,说的我迷迷糊糊。ok,堆栈是基本的数据结构,我懂,内存分布讲的也挺有道理,但就是感觉不对劲。那些文章光是语言上的阐述,有图的也就画个图,让我有些许疑惑,比如函数调用的溢出情况,是怎么回事?谷歌了几篇文章,还是找到了我的答案。
    每个浏览器对各自对js实现方式不一样,但大多大同小异。以Chrome为例子,其分内存分布形式为call stackmemory heap,栈和堆不了解的同学就自己百度,我不再赘述。

    2、Call stack(调用栈)

    调用栈的基本概念
    call stack调用栈在浏览器中的资源是有限的,是一开始就被分配好的,一般没有多大,几M乃至更小。
    该栈可以保存

    • 基本类型的变量(相同的变量的值,如a=2,b=2,它们是独立的,并不是共享一个2)
    • 引用类型指针(对象、函数)
    • 函数调用情况(非定义的指针),即一个函数及其参数情况(称之为一个栈帧call frame),通俗来说就是执行函数的时候

    这里着重讲栈帧,一个函数中调用其他函数(或者递归调用自己),会导致内部函数入栈形成一个函数帧,直到该函数内部执行完毕,才会出栈。
    注意到,即使是return一个栈帧也不会让该函数释放(很多编程语言实现了tail call 尾调用优化,ES6规定了尾调优化,但仍然许多浏览器不见优化,Chrome也是如此)。
    递归容易引起一系列的栈帧入栈,将会导致调用栈溢出,如这个例子

    function test(flag){
            retrun flag && test(--flag)
        }
    test(100000);//控制台报错:Uncaught RangeError: Maximum call stack size exceeded
    

    3、Memory heap(内存堆)

    这个,由需要定义的引用类型的大小决定,类似C语言的申请内存。
    函数、对象等引用类型都是保存在此处,栈中保存的是指向内存堆中的指针。
    这个没啥好讲的,不清楚是否有最大限制,貌似都是动态申请的,不然几十个动态页面那还得了?

    4、内存优化

    栈优化

    • 避免持续入栈,方法五花八门,百度的避免递归堆栈内存溢出的方案,大多都是这样
    • 尾调优化,慎用!原因之前讲了

    堆优化

    内存越来越大,电脑就会卡顿,不用的变量及时设置为null,让垃圾回收机制回收。

  • 相关阅读:
    Powershell 音乐播放
    Powershell指令集_2
    Powershell指令集_2
    Powershell 邮件发送
    Powershell 邮件发送
    Oracle 11g 关闭内存自动管理
    Oracle 11g 内存手动管理
    Oracle 内存参数调整
    RESTful三理解
    RESTful三理解
  • 原文地址:https://www.cnblogs.com/panshaojun/p/14168916.html
Copyright © 2011-2022 走看看