Javascript—为什么我的堆栈实现会导致大量GC事件?

Javascript—为什么我的堆栈实现会导致大量GC事件?,javascript,garbage-collection,Javascript,Garbage Collection,我用Javascript编写了一个堆栈实现,并将其作为名为“stack js implementation”的节点模块 您可以在此处查看源代码: function _StackItem(data, prev, next){ this.data = data; this.prev = prev; this.next = next; } function Stack(size){ this.maxSize = size; this.currentSize = 0; this

我用Javascript编写了一个堆栈实现,并将其作为名为“stack js implementation”的节点模块

您可以在此处查看源代码:

function _StackItem(data, prev, next){
  this.data = data;
  this.prev = prev;
  this.next = next;
}

function Stack(size){
  this.maxSize = size;
  this.currentSize = 0;
  this.head = null;
  this.last = null;
}

Stack.prototype.push = function(data){
  if (this.head === null) {
    var newStackItem = new _StackItem(data, null, null);
    this.head = newStackItem;
    this.last = newStackItem;
    this.currentSize += 1;
  }else{
    var originalTopStackItem = this.head; 
    var newStackItem = new _StackItem(data, null, originalTopStackItem);
    originalTopStackItem.prev = newStackItem;
    this.head = newStackItem; 

    if (this.currentSize === this.maxSize) {
      this.last.prev.next = null;
      this.last = this.last.prev;  
    }else{
      this.currentSize += 1; 
    }
  }
};

Stack.prototype.pop = function(){
  var topStackItem = this.head;
  if (topStackItem === null) {
    return this.head; 
  }

  this.currentSize -= 1;
  if (topStackItem.next === null) {
    this.head = null;
    this.last = null;
    return topStackItem.data;
  }else{
    this.head = topStackItem.next;
    return topStackItem.data;
  }
};
我实现自己的堆栈数据结构,因为我想限制堆栈大小。如果堆栈已达到最大大小,则execute
push
将删除堆栈的最底部元素,并将新元素推到堆栈的最顶部位置

我认为如果我使用传统的数组,它将花费大量时间移动,因此我使用链表构建它

在做了一些测试之后,我发现当大小达到最大值时,这个实现比数组更快地将新元素推送到堆栈中

但是在新元素达到最大大小之前将其推入堆栈比数组慢

这是我编写的测试代码:

var Stack = require('stack-js-implementation');
var s_own = new Stack(800000);
var s_internal = new Array();
var before, after;

console.log('--- own implementation ---\n');
before = Date.now();
for (var i = 0; i < 800000; i++) {
  s_own.push(i);
}
after = Date.now();
console.log('--- Add Elements to Stack Time --- : ' + (after-before) + '\n');

before = Date.now();
s_own.push(1000);
after = Date.now();
console.log('--- Push Time --- : ' + (after-before) + '\n');

console.log('\n\n');

console.log('--- internal implementation ---\n');
before = Date.now();
for (var i = 0; i < 800000; i++) {
  s_internal.push(i);
}
after = Date.now();
console.log('--- Add Elements to Stack Time --- : ' + (after-before) + '\n');

before = Date.now();
s_internal.shift();
after = Date.now();
console.log('--- Shift Time --- : ' + (after-before) + '\n');

before = Date.now();
s_internal.push(1000);
after = Date.now();
console.log('--- Push Time --- : ' + (after-before) + '\n');
var Stack=require('Stack-js-implementation');
var s_own=新堆栈(800000);
var s_internal=新数组();
var前、后;
log('--own实现--\n');
before=Date.now();
对于(变量i=0;i<800000;i++){
自推(i);
}
after=Date.now();
log('---将元素添加到堆栈时间---:'+(在之前之后)+'\n');
before=Date.now();
自推(1000);
after=Date.now();
log('---推送时间---:'+(在之前之后)+'\n');
console.log('\n\n');
console.log('---内部实现--\n');
before=Date.now();
对于(变量i=0;i<800000;i++){
s_内部推力(i);
}
after=Date.now();
log('---将元素添加到堆栈时间---:'+(在之前之后)+'\n');
before=Date.now();
s_internal.shift();
after=Date.now();
log('---班次---:'+(在之前之后)+'\n');
before=Date.now();
s_内部推力(1000);
after=Date.now();
log('---推送时间---:'+(在之前之后)+'\n');
我运行了这个概要文件(使用
节点--trace gc test.js
),发现问题在于它导致了很多gc事件


请帮帮我。谢谢。

我不认为在堆栈尚未满时在堆栈上推一个新项目会导致任何GC。创建一个对象并将其插入列表中。不应该有任何问题。一旦列表已满,如果没有其他引用,则从列表中踢出的旧对象将受到GC的约束。你认为GCed是什么?我使用命令
node--trace gc test.js运行它,我看到发生了很多gc事件。然后,你需要看看GCed到底是什么。在列表已满之前,您的
.push()
本身不应导致GC。如何获取此信息?我首先要简化测试,使其仅在堆栈容量不足的情况下执行一系列
.push()
操作。查看仅执行此操作时是否有大量GC操作。甚至没有任何
console.log()
语句或计时。只需执行
.push()
操作。