近似计算一个对象在js占用内存

内存

在很久之前,我就想查看一个对象在JS里占用多少内存了,直到最近由于线上使用了需要计算从服务端传输数据的大小,让这个需求尤为强烈。

预备知识

我们现在使用的js是高级语言,它在内存细节之上建立一个抽象层,目前我们接触到的,就是变量,变量的占用内存是固定了,语言规范声明的,但是由于实现解释器,可能一个类型的变量占用内存,会稍规范多一些,这里我们可以先忽略,这样,我们就可以按照规范定义的变量内存大小,来计算一个变量占用的内存了

js中的类型

undefined

null

boolean

number

string

object(区分普通数组和对象)

npm - object-sizeof

按照官方定义的数据类型大小,npm有一个包遍历对象,然后依次计算每个属性占用的内存,求和,就能得到对象的近似大小

npm install object-sizeof
  var sizeof = require('object-sizeof')
  
  // 2B per character, 6 chars total => 12B
  console.log(sizeof({abc: 'def'}))
  
  // 8B for Number => 8B
  console.log(sizeof(12345))
  
  var param = { 
    'a': 1, 
    'b': 2, 
    'c': {
      'd': 4
    }
  }
  // 4 one two-bytes char strings and 3 eighth-bytes numbers => 32B
  console.log(sizeof(param))
 

首先安装object-sizeof,然后引入即可得到对象大致大小

object-sizeof缺陷

好奇的我看了这个包的源码

function sizeOfObject (object) {
  if (object == null) {
    return 0
  }

  var bytes = 0
  for (var key in object) {
    if (!Object.hasOwnProperty.call(object, key)) {
      continue
    }

    bytes += sizeof(key)
    try {
      bytes += sizeof(object[key])
    } catch (ex) {
      if (ex instanceof RangeError) {
        // circular reference detected, final result might be incorrect
        // let's be nice and not throw an exception
        bytes = 0
      }
    }
  }

  return bytes
}
function sizeof (object) {
  if (Buffer.isBuffer(object)) {
    return object.length
  }

  var objectType = typeof (object)
  switch (objectType) {
    case 'string':
      return object.length * ECMA_SIZES.STRING
    case 'boolean': 
      return ECMA_SIZES.BOOLEAN // 4
    case 'number':
      return ECMA_SIZES.NUMBER //8
    case 'object':
      if (Array.isArray(object)) {
        return object.map(sizeof).reduce((acc, curr) => acc + curr, 0)
      } else {
        return sizeOfObject(object)
      }
    default:
      return 0
  }
}

首先在这里,null和undefined的内存被标记为0,这里是不正确的,然后是string类型的,同样是一个字符,中文占用的字节和英文不一样,对象的大小也没计算,但是还可以用

posted @ 2019-09-14 11:07  兴趣使然的Geek  阅读(7925)  评论(0编辑  收藏  举报