当前位置: 首页 > Web前端 > JavaScript

“堆栈内存”中是否存在“字符串”?那我林三心来跟踪你!

时间:2023-03-27 13:00:47 JavaScript

序大家好,我是林三鑫。用最通俗易懂的语言解释最难的知识点是我的座右铭。基础是进阶的前提是我的初衷。在我们的认知中:基本类型存放在栈内存中,引用数据类型存放在堆内存中。consta='林三鑫'constb={age:18,height:180}大家都知道超长字符串是基本类型,所以大家都认为字符串是存放在栈内存中的,但是你要知道,V8默认的栈内存是984Kib,那么超长的字符串>984Kib可以加载到栈内存吗?这是一个比较经典的问题——大象打包问题,问:大象能装进一个小盒子里吗?让我们仔细看看堆快照。先看一段代码constfunc=function(){this.str1='林三鑫'this.str2='Sunshine_Lin'}consta=newfunc()constb=newfunc()然后我们取一个查看堆快照的详细信息。从上面的结果可以看出,a和b的str1都指向同一个地址。a和b的str2都指向同一个地址。是不是可以猜出一个结论:字符串的内容存放在堆内存中,指针存放在栈内存中,同一个字符串指向同一个堆内存地址。修改和添加一个字符串,我们稍微修改一下代码constfunc=function(){this.str1='林三鑫'this.str2='Sunshine_Lin'}consta=newfunc()constb=newfunc()//修改str1a.str1='hahahahahahahahahahaha'//添加str3,同str2a.str3='Sunshine_Lin'我们来看看此阶段堆快照的详细信息。上面的结果可以看出:str1修改为新的字符串后,重新开辟了一块新的内存空间(新地址)。添加str3后,指针指向已有的Sunshine_Lin内存空间那么我们是否可以猜出一个结论:添加或修改一个字符串后,如果是之前不存在的字符串,则开辟一个新的内存空间,如果是一个已有的,直接使用已有的内存空间源码分析当我们声明一个字符串时:1.v8内部有一个名为stringTable的hashmap来缓存所有的字符串。在读取我们V8中的代码,转换抽象语法树的时候,每遇到一个字符串,就会根据它的特性,转换为hash值,插入到hashmap中。后面如果遇到哈希值相同的字符串,会先取出来进行比较。如果一致,则不会生成新的字符串类。2、缓存字符串时,根据不同的字符串采用不同的哈希方法。源码通俗易懂总结当我们创建一个新的字符串时,V8会搜索内存,看是否已经有相同的字符串,如果找到,就直接复用。如果找不到,则开辟新的内存空间存放字符串,并将地址赋给变量。你有没有想过为什么不能通过下标索引修改字符串?因为对字符串的修改本质上只是通过整体修改,而不是部分修改。结语我是林三鑫,一个狂热的前端菜鸟程序员。如果你有上进心,喜欢前端,想学前端,那我们可以交个朋友,一起钓鱼哈哈,摸摸鱼群,加我,请注意[思想]