求解答,nodejs超大数组导致内存不够的解决方案?

新手上路,请多包涵

我有很多个js数组,可能一秒存入一条数据,从0开始,比如现在到每个数组都有100万条数据了,但是我只用到最后的10万条数据,并且是用的数据下标来标记的,第90万就是arr[899999],我应该怎么处理啊?
把前面的数据delete会不会好一些,delete之后下标不会变,我只会想到这个,或者有什么好的解决方案?

而且程序重启的时候我希望恢复刚刚重启前的数据,怎么弄啊?

阅读 2.1k
3 个回答

搞一个10万长度的循环队列,每次有新的数据,都往里放。放满之后,就覆盖掉旧的数据。在大数量的情况下,可以复用之前的空间。

循环队列:

class CircleQueue {
  #list = [];
  #front = 0;
  #rear = 0; // 该指针表示下一个元素要存储的位置
  #maxSize = 10; // 存储的最大空间,若超出则淘汰旧数据

  constructor(maxSize = 10_0000) {
    if (typeof maxSize === "number" && maxSize > 0) {
      // 这里要判断尾指针是否追上了头指针,会空出一个位置,因此要+1才是真正的存储空间
      this.#maxSize = maxSize + 1;
    }
  }
  push(data) {
    this.#list[this.#rear] = data;
    this.#rear = (this.#rear + 1) % this.#maxSize;

    if (this.#rear == this.#front) {
      // 当尾指针追上了头指针,头指针向前移动,表示之前的元素被覆盖了
      this.#front = (this.#front + 1) % this.#maxSize;
    }
  }
  shift() {
    const element = this.list[this.#front];
    if (!this.empty()) {
      // 移除头部元素时,若数据不为空,则头指针向前移动
      this.#front = (this.#front + 1) % this.#maxSize;
    }
    return element;
  }
  // 清空数据
  empty() {
    this.#front = 0;
    this.#rear = 0;
  }
  // 判断是否为空
  isEmpty() {
    return this.#front === 0 && this.#rear === 0;
  }
  size() {
    return (this.#rear - this.#front + this.#maxSize) % this.#maxSize;
  }

  // 获取队列中的数据
  getList() {
    const list = [];
    let i = this.#front;

    while (i !== this.#rear) {
      list.push(this.#list[i]);
      i = (i + 1) % this.#maxSize;
    }

    return list;
  }
}

使用。比如我存储空间是6,但有20条数据:

const queue = new CircleQueue(6);
for (let i = 0; i < 20; i++) {
  queue.push(i);
  console.log(queue.getList());
}

image.png

可以看到,当存储空间满了之后,就开始覆盖旧的数据了,但存储空间没增长。

const max = 4
// 创建好固定超度的数组
let arr = new Array(max).fill(-1)

let count = 0
let intervalId = setInterval(()=>{
  if (count == 10) {
    console.log('arr ***  end', arr)
    clearInterval(intervalId)
  } else {
    // 将数据存入特定下标, 将下标用序号进行求余操作, 就可循环存入数组
    arr[count % max] = count
    console.log('arr add', arr)

    if (count == 7) {
      // 此时我想取数据
      console.log('get -------------')

      const index = (count + 1) % max
      let result = count+1 < max 
          // 没有被循环存直接取
        ? arr.slice(0, index)
        // 循环存入了, 从当前下标的后一个开始取, 取到末尾, 再从第一个取到当前下标(最后一个)
        : [...arr.slice(index), ...arr.slice(0, index)]  

      
      console.log(result)
      console.log('-------------')
    }

    count++
  }
}, 100)

感觉这更像是业务问题。

不要总是尝试用技术解决业务问题吧。

十万条数据也太多了点

推荐问题
logo
Microsoft
子站问答
访问
宣传栏