欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript的内存机制浅谈

程序员文章站 2022-04-11 17:06:28
...

一、简述

     Java与JavaScript均是编程语言,强类型与弱类型(渐进式与非渐进式),根据编程语言之间的差异,那么他们的内存机制自然存在则一定的差异.

     本章博客主要想与各位开发者(DL)们一起探讨关于JavaScript这门编程语言的内存机制,嘿嘿.

     讨论主题: JavaScript的局部变量被内存回收问题  (基于有比较强的内存空间感)

      博主:在讨论中被喷,在被喷中成长的人 (题外话)

二、内存机制

     JavaScript的内存机制:内存基元(基元:相当与单位内存空间)  在变量创建时自动分配,当变量不被使用时,则被视为"垃圾"自动回收。"垃圾"被谁回收了呢? JavaScript的垃圾回收线程,采用变量标记算法及根据闭包原理进行回收,

     基于讨论的主题是JavaScript的局部变量回收问题,引出3个问题:

     (1) JavaScript全局变量与局部变量的生命周期;

     (2) JavaScript变量在何时会被垃圾回收线程回收;

     (3) JavaScript的基本数据类型与引用数据类型有哪些,何时被回收呢?

    JavaScript内存模型图(注:非原型内存模型,可浏览参考博客中的文章获取知识源泉):

     JavaScript的内存机制浅谈

      在进行图解之前,先灌输一波概念:JavaScript的基本数据类型及引用数据类型有哪些的问题。

      基本数据类型:Number (数值) String(字符串)  Null (空值) Undefined(未定义) Boolean(布尔,真假类型)

      引用数据类型: Array(数组) Object(对象) 等等自定义对象.

      总结:非引用的数据类型就是基本数据类型...

      图解1:内存模型中,JavaScript的内存分为堆、栈、池(一般归为栈)  -->与Java的内存模型不太相同,但是主体是雷同的。

                   基本数据类型的变量创建均在栈内存中,只是针对于基本数据类型。(对象的属性中有基本数据类型,而他们在堆内存)

                   

​
<script type="text/javascript">
		
			//页面加载完成后,回掉该函数.
	$(document).ready(function(){
				
		var varible1 = 10; 			//值类型
		var varible2 = "Xiao Ming"; //字符串
		var varible3 = null;		//空值
		var varible4 = true;		//布尔
				
		console.log(typeof(varible1));//number
		console.log(typeof(varible2));//string
		console.log(typeof(varible3));//object
		console.log(typeof(varible4));//boolean
		console.log(typeof(varible5));//undefined
				
	});
		
</script>

​

      图解2:  基本数据类型基本都是值传递,而引用类型当然设计为引用传递了. (引用传递与值传递自行脑部或参考其他博客)

三、内存回收

     问题1:JavaScript的全局变量与局部变量的生命周期。

              (1)全局变量与局部变量生命周期

               全局变量当声明时,并一致作用于文档中,直到文档被浏览器"卸载"后,才被垃圾回收线程标记为可回收部分。

               局部变量当声明时,只作用与该方法、函数中,该方法执行完毕后,引用变量被标记为可回收部分,等待垃圾回收线程                 来回收。(重点:当该函数中存在回掉函数时,且回调函数引用该变量时,则该变量不会被标记为可回收部分.)

                (这也就造成了,回调函数引用的局部变量假装成为了全局变量的问题...) ****

                (请各位看官,多多指点,是否真如我所说的! 如果是真的,麻烦评论回复一下,谢谢各位大佬)

      问题2:JavaScript的变量何时被垃圾回收器回收呢? (已简略的在问题一中回答.)

四、内存机制小结

      小结部分:主要用于验证上述所说的正确性,采用(逻辑+代码+结果)的方式来验证.

       验证问题1:JavaScript的全局变量与局部变量的生命周期问题.

       逻辑:如果是全局变量,且文档不被卸载的情况下,在全局访问变量声明后的任何一个函数或方法均可以访问到;

                  反之,则后面的函数均访问不到

       代码:

          

<script type="text/javascript">
		
		     //1.定义全局变量;
		     var global_varible = "我是全局变量";
		     
		     //2.定义函数.
		     function testFun(){
		    	var part_varible = "我是局部变量"
		        console.log(global_varible); 
		     }
		     
		     $(function(){
		    	 //如果控制台输出:我是全局变量,则说明全局生命周期正确.
		    	 testFun();
		         //如果控制台输出:我是局部变量,则说明局部声明周期错误,反之,则正确.
		         console.log(part_varible);
		     });
		     
		</script>

    结果:  正常输出,不做贴图操作...(注:暂时不验证,局部变量在回调函数中处于一个假的全局变量问题)

   局部变量处于假的全局变量问题验证设计如下:

    1.$(document).ready(function(){

          //1.声明该变量,并定义为null

         //2.为某个元素1动态绑定点击事件,回调函数修改该变量

         //3.继续为另外一个元素2动态绑定点击事件,回调函数输出该变量;

         // 操作流程:首先,如果点击元素2,返回的是null,且 点击元素1再点击元素2返回的是修改的值,说明理论验证成功.

         //验证逻辑:如果点击元素2,输出是null,说明:该引用变量已经被回调函数引用,此时且已经引用完了,应该被回收且标            记,那么再点击元素1后点击元素2,此时:应该还是null,说明局部变量在该函数执行结束后,直接释放了内存空间。

         //反之,如果点击元素1,再点击元素2,输出的是修改的值,那么说明局部变量已经变成了所谓的假全局变量,且一直被引用下去。

                (除非元素1、元素2移除绑定事件外,那么该假全局变量就变成了真局部变量被回收了)

    });

 

 

注:以上结论均来源于开发过程中,所思考的问题!

参考博客:https://www.cnblogs.com/yangmin86/p/7090882.html

                  https://www.cnblogs.com/sachen/p/6659680.html  (内存模型图)

                  https://blog.csdn.net/feiying008/article/details/52840944 (原型内存模型详解)