V8如何存储像5这样的整数?

4

V8如何在内存中存储整数?

例如,整数5如何存储?

我知道它将其存储在堆中,但它具体是如何存储的呢? 这些元数据以及实际值本身,是否会在存储之前添加常量?


1
JavaScript中的所有数字都是8字节浮点值。 - Pointy
变量在内存中是否添加了某种常量? - Спасимир Павлов
1
@Pointy 或许是因为了解可表示数字的范围可以帮助避免溢出错误。或者因为您想知道整数除法是否发生截断。或者因为了解这样的细节可能会影响优化决策,或有助于调试。或者您正在设计自己的脚本语言,想知道其他语言是如何处理的。或者仅仅是因为获取知识本身没有错。 - Ray
1
@Ray,m/22.5,因为所有的值都是浮点数,所以这并不奇怪。另一个值为0,是因为语言规范中定义了<<截断为int32的2进制补码形式,而不是引擎的表示选择(对于i=30,n变成2^31,对于i=31,1<<i变成-2^31,所以总和恰好为0)。 - Andreas Rossberg
@Superfly的回答和链接的源代码表明为什么表示“小”整数很重要:它会影响性能和存储分配。例如,考虑生成一个循环的代码,该循环迭代从1到一百万的整数。聪明地表示整数可以使这段代码运行得更快,并且可能减少内存分配和垃圾收集的压力。 - Cris P
显示剩余3条评论
2个回答

11

V8使用指针标记方案来区分小整数和堆对象指针。数字5将被存储为Smi类型,在V8中不需要在堆上进行分配。

您可以查看源代码了解更多关于Smi类的信息。

在32位平台上,Smis是一个带有底部位设置为0的31位有符号整数。 在64位平台上,Smis是一个带有31位0填充和底部位设置为0的32位有符号整数。 指向堆对象的指针底部位设置为1,以便V8可以在没有额外元数据的情况下区分指针和Smis。


3
由于指针压缩技术,现代版本的V8在64位平台上将SMI存储为31位整数。这使得指针可以用4个字节来存储,从而大幅减少内存消耗。 - shitpoet

-4
在Javascript中,所有数字都以64位浮点数值存储。C和C++将此类型称为double。没有明确的“整数”类型。
在某种程度上,您可以天真地使用整数值并获得您期望的结果,而不必担心舍入误差。这些整数被称为“安全”整数。
范围内的所有整数[ - (2^53 - 1),+ (2^53 - 1)]都是“安全”整数,如此处所述。这意味着,如果您在该范围内添加、减去或乘以整数,并且结果也在该范围内,则计算不会出现舍入误差。
当然,Javascript/V8中的所有值都以某种方式“封装”,因为变量没有类型(除了使用标记指针的小整数)。如果您有一个变量x,它是5.25,它必须知道它是一个“数字”,并且该数字是5.25。因此,它将占用超过8个字节的空间。您将需要查找v8的源代码以了解更多信息。

4
不正确。V8和其他大多数语言运行时一样,会将小整数(在V8中缩写为“smi”)拆箱成单个(标记的)字。 - Andreas Rossberg
@AndreasRossberg 这可能是真的,但语言规范很清楚:数字是64位双精度浮点值。内部优化对程序员来说是不透明的,否则实现就是有问题的。 - Pointy
7
@Pointy的回答是正确的,但与问题无关,因为原帖的问题明确是关于实现而不是语言规范的。 - Andreas Rossberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接