Javascript—为什么我的堆栈实现会导致大量GC事件?
我用Javascript编写了一个堆栈实现,并将其作为名为“stack js implementation”的节点模块 您可以在此处查看源代码: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
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;
}
};
我实现自己的堆栈数据结构,因为我想限制堆栈大小。如果堆栈已达到最大大小,则executepush
将删除堆栈的最底部元素,并将新元素推到堆栈的最顶部位置
我认为如果我使用传统的数组,它将花费大量时间移动,因此我使用链表构建它
在做了一些测试之后,我发现当大小达到最大值时,这个实现比数组更快地将新元素推送到堆栈中
但是在新元素达到最大大小之前将其推入堆栈比数组慢
这是我编写的测试代码:
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()
操作。