位置: 编程技术 - 正文

JavaScript对内存分配及管理机制详细解析(js 对象内存 占用)

编辑:rootadmin

你可能听说过JAVA、.NET、PHP这些语言有垃圾回收的内存管理机制,但是很少会听到JavaScript也有自己的内存管理机制,JavaScript同样有着类似的垃圾回收功能。本文主要讲述了JavaScript的垃圾回收原理和具体的过程。

简介在底层语言中,比如C,有专门的内存管理机制,比如malloc() 和 free()。而Javascript是有垃圾回收(garbage collection)机制的,也就是说JS解释器会自动分配和回收内存。这样就有人觉得,我用的是高级语言,就不用关心内存管理了,其实这是不对的。

内存的生命周期尽管语言不尽相同,而每种语言中内存的生命周期都是相似的:

1.当需要的时候分配内存2.对内存进行读写操作3.当上面分配的内存不再需要的时候,将他们释放掉对于1,2两步,几乎所有语言操作起来都是明确地或者说很直观,没什么好说的。而在像Javascript一样的高级语言中,第三步操作就显得不那么直观。

Javascript中分配内存空间变量初始化当变量初始化的时候,Javascript会自动分配相应的内存空间(注:这里MDN上关于这里用的是Value initialization,到底是声明,还是在赋值时候分配空间,还要再学习一下)

var n = ; // 为数字分配空间var s = “azerty”; // 字符串

var o = {a: 1,b: null}; // 为对象和它包含的属性分配内存空间

var a = [1, null, "abra"]; // (类似对象)给数组和它里面的元素分配空间

function f(a){return a + 2;} // 为函数分配空间

// 函数有时也会为分配对象空间someElement.addEventListener(‘click', function(){someElement.style.backgroundColor = ‘blue'; //个人补充,未考证,这里会为someElement分配空间,如注释所说,为对象分配空间}, false);

函数调用时候分配空间有的函数调用,会产生上面说的那种 为对象分配空间

var d = new Date();var e = document.createElement('div'); // allocates an DOM element还有下面这种

var s = “azerty”;var s2 = s.substr(0, 3); // s2 is a new string// 由于Javascript中字符串是不可变的,所以Javascript也许并没有为s2中的字符串分配新空间,而是只存了[0, 3]的区间(用来索引)

var a = ["ouais ouais", "nan nan"];var a2 = ["generation", "nan nan"];var a3 = a.concat(a2); // 新的空间来存储数组a3

操作变量值没什么好说的,读、写、函数调用。

内存不再被使用时,将它们释放掉许多内存管理机制的问题都出现在这里。最麻烦的问题是确认“这块内存空间已经不需要了”。这往往需要程序员告知,这个程序中,这块内存已经不需要了,你们回收吧。

而高级语言解释器中嵌入了一个叫做“垃圾回收(garbage collector)”的工具,用来跟踪内存分配和使用情况,以便在它们不需要的时候将其自动回收。然而有个问题,一块内存空间是不是还有用,是具有不确定性的,也就是说,这个是没法用算法精确算出来的。

垃圾回收如上所述原因,垃圾回收机制采取了一种有限的解决方案来处理上面的不确定性问题。下面介绍集中垃圾回收算法的思想以及相应的局限:

引用这种方法,用到了一种引用的思想。当a能访问A时,就说A引用了a(不论是直接还是间接的)。比如,一个Javascript对象会引用他的原型(间接引用)和它的各个属性(直接引用)。

这种情形下,对象就被扩展的更广义了,在原生对象的基础上,还包含了函数的作用域链(或者全局的词法作用域)。

引用计数这种方法是最拿衣服(naive)的垃圾回收算法。它把“可以回收”的标准定义为“没有其他人引用这个对象”(原文:This algorithm reduces the definition of “an object is not needed anymore” to “an object has no other object referencing to it”)。也就是说,只有当对象没有被引用的时候,才会被当作垃圾回收掉。

举个例子var o = { // 称之为外层对象a: { //称之为内层对象b:2}}; // 创建了两个对象 内层对象作为外层对象的属性而被引用// 而外层对象被变量o引用// 显然,没有人会被垃圾回收

var o2 = o; // o2也引用了上面说的外层对象。好现在外层对象的引用计数为‘2' (被o和o2引用)o = 1; // 现在o不再引用外层对象,只有o2在引用,引用计数为 ‘1'

var oa = o2.a; // oa 引用内层对象// 现在内层对象同时被作为外层对象的属性引用和被oa引用,引用计数为‘2'

o2 = “yo”; // 好,现在o2也不引用外层对象了,外层对象引用计数为“0”// 意味着外层对象可以被“垃圾回收”了// 然而,内层对象还被oa引用着,因此还是没有被回收 (个人注释:这里有一点闭包的意味)

oa = null; // 现在oa不引用内层对象了// 内层对象也被垃圾回收

局限:循环引用

看下面代码:

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

return “azerty”;}

f();// o o2两个对象构成了循环引用// 当函数执行完毕的时候,他们就被关在了f的作用域里面,没有外面的人可以使用他们// 所以按理说,他们已经没有存在价值了,需要被垃圾回收,释放内存// 然而,他们的引用计数都不为“0”// 所以在这种引用计数的机制下,他们没有被回收

实际例子在IE6,7版本的浏览器中,就是使用的引用计数机制。因此,下面的代码在IE6,7中可以稳稳地发生内存泄漏

var div = document.createElement("div");div.onclick = function(){ doSomething();}; // div的onclick属性,会引用 function// 然而这个 function 反过来又引用了这个div,因为div在handler的作用域里面。// 造成上述循环引用,导致内存泄漏。标记清除算法

这种算法把“可以回收”定义成“对象不可达”,即访问不到。

这种算法,会定义一个“根”,并且定期地从“根”出发,找出“根”下面的所有对象,看能不能从“根”找到一条路径引用到这个对象。从不同的“根”出发,垃圾回收程序就可以区分所有对象是不是“不可达”的,当对象“不可达”时候,便被回收。

这种算法比引用计数算法要好些。因为 “一个对象的引用计数是0”可以推出“这个对象不可达”,逆命题则为假。也就是说这种算法扩充了垃圾回收的范围。

循环引用不再是困扰在上面的循环引用例子中,当函数返回时,o 和 o2都已经不再被任何人引用,也就是“不可达”了,便顺理成章地被垃圾回收掉了。

局限:对象需要明确的“不可达”虽然说是局限,然而这种情况在实际当中很少发生,因此很少有人关注这一点。

推荐整理分享JavaScript对内存分配及管理机制详细解析(js 对象内存 占用),希望有所帮助,仅作参考,欢迎阅读内容。

JavaScript对内存分配及管理机制详细解析(js 对象内存 占用)

文章相关热门搜索词:js对象在内存中的存储,js导致内存泄露的几种问题,js 对象内存 占用,js 对象内存 占用,javascript内存管理,js内存释放,javascript内存机制,javascript内存管理,内容如对您有帮助,希望把文章链接给更多的朋友!

javascript中怎么做对象的类型判断 最近在翻看JohnResig的大作《ProJavaScriptTechniques》,里面讲到了如何做javascript的类型判断的问题。文中介绍了两种方式,一种是使用typeof,另一种是使用co

JavaScript中判断对象类型的几种方法总结 我们知道,JavaScript中检测对象类型的运算符有:typeof、instanceof,还有对象的constructor属性:1)typeof运算符typeof是一元运算符,返回结果是一个说明运算

JavaScript splice()方法详解 定义和用法splice()方法用于插入、删除或替换数组的元素。语法arrayObject.splice(index,howmany,element1,.....,elementX)参数描述index必需。规定从何处添加/删除元素

标签: js 对象内存 占用

本文链接地址:https://www.jiuchutong.com/biancheng/373636.html 转载请保留说明!

上一篇:javascript中的throttle和debounce浅析(JavaScript中的变量名不区分大小写)

下一篇:javascript中怎么做对象的类型判断(javascript中怎么创建一个数组)

  • 房产税的房产原值是什么
  • 纳税申报期限是纳税期限期满后的时间
  • 资产负债表其他流动资产计算公式
  • 冲回多提的坏账准备分录为
  • 小企业一定要买五险吗
  • 财务报表申报错误怎么办
  • 非盈利机构怎么说
  • 公司为员工买零食
  • 计提工资需要纳税调整吗
  • 未达起征点销售额怎么填申报表
  • 个人独资企业的优缺点
  • 2019年小型微利企业优惠政策
  • 外资企业享受什么优惠政策
  • 有限责任公司应当具备的条件
  • 应收票据主要包括
  • 固定资产清理增加记哪一方
  • 银行期初数不对,怎么调整
  • 仲裁费用计入什么会计科目
  • 餐饮 专票
  • 车辆增值税抵扣多少点
  • 滞留发票产生的原因主要包括哪些?
  • 机动车销售统一票据可以抵扣吗
  • 兼营小规模纳税人增值税优惠
  • 民办学校都没有编制吗
  • 本单位员工投稿怎么写
  • 个人营业执照怎么注销网上申请流程
  • 一张发票上可以开几行
  • 视同销售的计税依据
  • windows 10如何清除联网记录
  • 公司收到个人的款怎么做账务处理
  • 货款形式返还
  • 试用期人员工资财务记账
  • 政府搬迁补偿款怎么算
  • 企业实际发生的经济业务事项都需要
  • 最高成本的手机是哪款
  • 计算机网络的基本概念
  • yii2实现根据时间搜索的方法
  • 多表关联join
  • 选择器优先级
  • 错账的类型及对应的更正方法
  • 财务管理中的折现率是指什么
  • 转出未交增值税借方余额表示什么
  • phpcms api
  • sql merge语句
  • 长期无法收回的应收账款如何处理
  • 负债类账户期末余额在借方还是贷方
  • Keepalived+HAProxy实现MySQL高可用负载均衡的配置
  • 小企业会计准则2023电子版
  • 运输途中的合理损耗计入入账价值
  • 一般纳税人跨年冲红报年度所得税怎么做
  • 税控服务费减免月底怎样结转
  • 进项税抵扣的分录怎么做
  • 给员工的奖金计入什么科目
  • 如何确定交易性金融资金
  • 动漫产业增值税率是多少
  • 增值税专用发票怎么开
  • 工程施工怎么做账
  • 收到垫付款计入什么科目
  • 三代手续费企业所得税
  • 工程项目必须购买保险吗
  • 施工图审查费计算公式
  • 专家咨询费支付标准
  • 预装win10
  • xp系统ie浏览器怎么升级
  • win10控制面板中没有防火墙
  • u盘设置背景音乐怎么弄
  • ghoststartservice.exe是什么进程 有什么作用 ghoststartservice进程查询
  • win7一键共享软件
  • Win10 Mobile Redstone预览版14295出现问题 屏幕闪烁/应用自动关闭等
  • perl -p -i
  • js鼠标移入事件
  • js实现隔行换色
  • 使用jquery实现的项目
  • android获取手机的基本信息
  • Android的PopupWindow使用android学习之旅(四十三)
  • 怎么查其他公司的财务报表
  • 国家电子税务登录入口
  • 如何做好巡察组组员
  • 福州灵活就业社保缴费2024年多少钱
  • 如果我是科学家我会发明什么
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设