JAVASCRIPT:V8问题:小整数可以重复使用吗?

JavaScript: V8 question: are small integers reused?(JAVASCRIPT:V8问题:小整数可以重复使用吗?)
本文介绍了JAVASCRIPT:V8问题:小整数可以重复使用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据V8的博客this article和this existing question,我们知道小整数直接通过指针标记编码到指针中。

SMI的诀窍在于它们不会存储为单独的对象:当您有一个引用SMI的对象时,例如let foo={smi:42},则可以对值42进行SMI编码并直接存储在该对象中(而如果该值为42.5,则该对象将存储一个指向单独&q;HeapNumber&q;的指针)。但由于对象在堆上,所以SMI也在堆上。

这意味着如果我有两个不同的对象具有相同的对象值{smi: 42}。SMI42应该位于堆上的两个不同的内存位置,因为这两个对象位于堆上,并且值42直接编码到指针中,而不是具有额外的存储空间。

但这与Chrome开发工具的内存分析结果相矛盾。给定此代码段

<body>
    <button id='btn'>btn</button>
    <script>  
    const btn = document.querySelector('#btn')
    function MyObject() {
        this.number = 3.14
        this.smi = 123
        this.undefined = undefined
        this.true = true
        this.false = false
        this.null = null
        this.string = 'foo'
    }
    let obj1
    let obj2
    btn.onclick = () => { 
        obj1 = new MyObject()
        obj2 = new MyObject()
    }
    </script>
</body>

我认为smi:123应该位于两个不同的位置,而双精度number = 3.14应该指向相同的数字对象。

但实际情况并非如此--smi位于相同的内存位置,而Double不在相同的内存位置。

推荐答案

对@JonasWilms的精彩回答的补充评论:

如果您真正关心幕后发生的事情,我建议您学习如何使用(本机,而不是DevTools)调试器并检查实际内存。DevTool旨在帮助您了解您的应用程序正在做什么,虽然这与揭示幕后发生的事情有很多重叠之处,但这并不完全是一回事,而且很可能会有某些细节(比如SMI的呈现方式)显示出这种差异。我认为堆快照使用raw_address → object ID映射,您所看到的是将SMI放入这样的映射中的自然结果。

对于测试用例的简化版本(只需function MyObject() { this.number = 12.5; this.smi = 23; }),您将在内存中看到以下内容:

(gdb) x/5xw 0x1f010810aedc
0x1f010810aedc: 0x082c7db1  // pointer to map
                0x08002249  // pointer to properties (empty array)
                0x08002249  // pointer to elements (empty array)
                0x0810af71  // pointer to a HeapNumber
                0x0000002e  // Smi: 23 << 1 == 46 == 0x2e
(gdb) x/5xw 0x1f010810afa4
0x1f010810afa4: 0x082c7db1  // map (same as other object)
                0x08002249  // properties
                0x08002249  // elements
                0x0810afd9  // pointer to a HeapNumber
                0x0000002e  // Smi: 23 << 1

另外,HeapNumbers可以而且确实可以被重用。我们在本例中没有看到这一点,因为还有另一种机制:对象属性使用可变HeapNumbers。可变使得它们不可共享,在这个玩具示例中,整个方法只是浪费时间和内存;但事实证明,对于典型的使用模式,这是一个有益的权衡,因为它允许更新值(特别是从优化的代码),而不需要每次都分配新的HeapNumber。
如果您只有一个function f() { return 12.5; },它实际上会在每次调用时返回相同的重复使用的HeapNumber。

这篇关于JAVASCRIPT:V8问题:小整数可以重复使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)