「字符串」存在「栈内存」?那我可要杠你了哦!

开发 前端
当我们新建一个字符串时,V8会从内存中查找一下是否已经有存在的一样的字符串,找到的话直接复用。如果找不到的话,则开辟一块新的内存空间来存这个字符串,并把地址赋给变量。

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。

在我们的认知里:基础类型存栈内存,引用数据类型存堆内存。

const a = '林三心'
const b = {
    age: 18,
    height: 180
}

图片图片

超长字符串

大家都知道,字符串属于基础类型,所以大家会觉得字符串是存在栈内存中的,但是大家要知道,V8默认栈内存是984Kib,那如果一个超长字符串 > 984Kib能装的进栈内存吗?这也就是一个比较经典的问题——大象装箱问题,试问:一头大象能装进一个小箱子里吗?

图片图片

一探究竟

堆快照

先来看一段代码

const func = function() {
  this.str1 = '林三心'
  this.str2 = 'Sunshine_Lin'
}

const a = new func()
const b = new func()

然后咱们来看看堆快照的详情

图片图片

上面的结果可以看出:

  • a 和 b的str1都指向同一个地址
  • a 和 b的str2都指向同一个地址

那我们可不可以猜测出一个结论:字符串的内容存于堆内存中,指针存于栈内存中,且相同的字符串指向同一个堆内存地址

修改和新增字符串

我们稍微修改下代码

const func = function() {
  this.str1 = '林三心'
  this.str2 = 'Sunshine_Lin'
}

const a = new func()
const b = new func()

// 修改str1
a.str1 = '哈哈哈哈哈哈哈哈哈哈'
// 新增str3,跟str2一样
a.str3 = 'Sunshine_Lin'

再来看看现阶段的堆快照的详情

图片图片

上面的结果可以看出:

  • str1修改成一个新的字符串后,重新开辟了一个内存空间(新地址)
  • str3新增之后,指针指向已有的Sunshine_Lin的内存空间

那我们可不可以猜测出一个结论:新增或者修改字符串后,如果是一个之前不存在的字符串,则新开辟内存空间,如果是已有的,则直接使用已有的内存空间

源码分析

当我们声明一个字符串时:

  • 1、v8内部有一个名为stringTable的hashmap缓存了所有字符串,在V8阅读我们的代码,转换抽象语法树时,每遇到一个字符串,会根据其特征换算为一个hash值,插入到hashmap中。在之后如果遇到了hash值一致的字符串,会优先从里面取出来进行比对,一致的话就不会生成新字符串类。
  • 2、缓存字符串时,根据字符串不同采取不同hash方式。

图片图片

源码

图片图片

图片图片

通俗易懂总结

字符串的数据存于 堆内存 中,栈内存 中只是存其 地址指针

当我们新建一个字符串时,V8会从内存中查找一下是否已经有存在的一样的字符串,找到的话直接复用。如果找不到的话,则开辟一块新的内存空间来存这个字符串,并把地址赋给变量。

大家有没有想过,为什么字符串不能通过下标索引来进行修改呢?因为字符串的修改本质上只能是通过整个的修改,而不能局部修改。

责任编辑:武晓燕 来源: 前端之神
相关推荐

2024-04-01 08:41:39

字符串.NET

2018-02-05 10:18:42

技术管理注意

2021-09-10 08:18:31

Go语言字符串

2021-09-07 09:23:07

C++字符串算法

2021-12-10 08:17:48

字符串拼接场景

2024-06-12 13:54:37

编程语言字符串代码

2021-09-07 06:40:25

贪心平衡字符串

2011-04-12 09:40:01

JDK内存

2019-08-06 15:06:35

2009-06-23 14:13:00

Java字符串

2010-09-09 11:48:00

SQL函数字符串

2022-07-11 22:53:59

JavaScrip编译信小程序

2011-08-10 18:47:18

Cocoa字符串

2009-07-16 17:01:09

Swing字符串

2023-01-11 16:49:13

MySQL数据库

2014-01-02 16:14:10

PostgreSQL字符串

2021-03-08 08:23:24

Java字符串截取

2010-11-26 09:51:54

MySQL字符串

2010-06-28 15:18:51

SQL Server

2024-07-03 08:15:39

C#字符串表达式
点赞
收藏

51CTO技术栈公众号